@limetech/lime-elements 39.34.0 → 39.34.2

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 (309) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/{checkbox.template-CHtKKyY1.js → checkbox.template-BLkvZRs6.js} +1 -1
  3. package/dist/cjs/{index-BjHIBY-I.js → index-8x93m5oI.js} +57 -21
  4. package/dist/cjs/{index-BgFEL6FF.js → index-ETPz91V5.js} +10 -0
  5. package/dist/cjs/lime-elements.cjs.js +2 -2
  6. package/dist/cjs/limel-3d-hover-effect-glow.cjs.entry.js +2 -2
  7. package/dist/cjs/limel-action-bar_3.cjs.entry.js +4 -4
  8. package/dist/cjs/limel-ai-avatar.cjs.entry.js +2 -2
  9. package/dist/cjs/limel-badge.cjs.entry.js +3 -3
  10. package/dist/cjs/limel-banner.cjs.entry.js +2 -2
  11. package/dist/cjs/limel-breadcrumbs_8.cjs.entry.js +9 -9
  12. package/dist/cjs/limel-button-group.cjs.entry.js +2 -2
  13. package/dist/cjs/limel-button.cjs.entry.js +3 -3
  14. package/dist/cjs/limel-callout.cjs.entry.js +2 -2
  15. package/dist/cjs/limel-card.cjs.entry.js +2 -2
  16. package/dist/cjs/limel-chart.cjs.entry.js +1 -1
  17. package/dist/cjs/limel-checkbox.cjs.entry.js +3 -3
  18. package/dist/cjs/limel-chip-set.cjs.entry.js +2 -2
  19. package/dist/cjs/limel-chip_2.cjs.entry.js +2 -2
  20. package/dist/cjs/limel-circular-progress.cjs.entry.js +2 -2
  21. package/dist/cjs/limel-code-diff.cjs.entry.js +75 -34
  22. package/dist/cjs/limel-code-editor.cjs.entry.js +2 -2
  23. package/dist/cjs/limel-collapsible-section.cjs.entry.js +2 -2
  24. package/dist/cjs/limel-color-picker-palette.cjs.entry.js +3 -3
  25. package/dist/cjs/limel-color-picker.cjs.entry.js +2 -2
  26. package/dist/cjs/limel-config.cjs.entry.js +1 -1
  27. package/dist/cjs/limel-date-picker.cjs.entry.js +1 -1
  28. package/dist/cjs/limel-dialog.cjs.entry.js +3 -3
  29. package/dist/cjs/limel-dock-button.cjs.entry.js +1 -1
  30. package/dist/cjs/limel-dock.cjs.entry.js +3 -3
  31. package/dist/cjs/limel-drag-handle.cjs.entry.js +2 -2
  32. package/dist/cjs/limel-dynamic-label.cjs.entry.js +1 -1
  33. package/dist/cjs/limel-email-viewer.cjs.entry.js +2 -2
  34. package/dist/cjs/limel-file-dropzone_2.cjs.entry.js +3 -3
  35. package/dist/cjs/limel-file-viewer.cjs.entry.js +62 -50
  36. package/dist/cjs/limel-file.cjs.entry.js +2 -2
  37. package/dist/cjs/limel-flatpickr-adapter.cjs.entry.js +2 -2
  38. package/dist/cjs/limel-flex-container.cjs.entry.js +2 -2
  39. package/dist/cjs/limel-form.cjs.entry.js +7831 -6820
  40. package/dist/cjs/limel-grid.cjs.entry.js +2 -2
  41. package/dist/cjs/limel-header.cjs.entry.js +2 -2
  42. package/dist/cjs/limel-help-content.cjs.entry.js +2 -2
  43. package/dist/cjs/limel-help.cjs.entry.js +3 -3
  44. package/dist/cjs/limel-helper-line.cjs.entry.js +3 -3
  45. package/dist/cjs/limel-hotkey_4.cjs.entry.js +6 -6
  46. package/dist/cjs/limel-icon-button.cjs.entry.js +2 -2
  47. package/dist/cjs/limel-icon.cjs.entry.js +2 -2
  48. package/dist/cjs/limel-info-tile.cjs.entry.js +3 -3
  49. package/dist/cjs/limel-list-item.cjs.entry.js +5 -5
  50. package/dist/cjs/limel-markdown.cjs.entry.js +4 -4
  51. package/dist/cjs/limel-masonry-layout.cjs.entry.js +2 -2
  52. package/dist/cjs/limel-menu-item-meta.cjs.entry.js +2 -2
  53. package/dist/cjs/limel-picker.cjs.entry.js +2 -2
  54. package/dist/cjs/limel-popover_2.cjs.entry.js +3 -3
  55. package/dist/cjs/limel-profile-picture.cjs.entry.js +1 -1
  56. package/dist/cjs/limel-progress-flow-item.cjs.entry.js +1 -1
  57. package/dist/cjs/limel-progress-flow.cjs.entry.js +1 -1
  58. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +1833 -1639
  59. package/dist/cjs/limel-radio-button-group.cjs.entry.js +2 -2
  60. package/dist/cjs/limel-radio-button.cjs.entry.js +3 -3
  61. package/dist/cjs/limel-select.cjs.entry.js +3 -3
  62. package/dist/cjs/limel-shortcut.cjs.entry.js +2 -2
  63. package/dist/cjs/limel-slider.cjs.entry.js +3 -3
  64. package/dist/cjs/limel-snackbar.cjs.entry.js +3 -3
  65. package/dist/cjs/limel-split-button.cjs.entry.js +3 -3
  66. package/dist/cjs/limel-switch.cjs.entry.js +2 -2
  67. package/dist/cjs/limel-tab-bar.cjs.entry.js +3 -3
  68. package/dist/cjs/limel-tab-panel.cjs.entry.js +2 -2
  69. package/dist/cjs/limel-table.cjs.entry.js +255 -154
  70. package/dist/cjs/limel-text-editor-link-menu.cjs.entry.js +4 -4
  71. package/dist/cjs/limel-text-editor.cjs.entry.js +2 -2
  72. package/dist/cjs/loader.cjs.js +1 -1
  73. package/dist/cjs/{markdown-parser-BIa99LAc.js → markdown-parser-F3YRMjcy.js} +363 -370
  74. package/dist/cjs/{render-list-component-DgRQ8H3v.js → render-list-component-DAV1Dyg1.js} +1 -1
  75. package/dist/collection/collection-manifest.json +2 -1
  76. package/dist/collection/components/3d-hover-effect-glow/3d-hover-effect-glow.js +1 -1
  77. package/dist/collection/components/action-bar/action-bar-item/action-bar-overflow-menu.js +1 -1
  78. package/dist/collection/components/action-bar/action-bar.js +2 -2
  79. package/dist/collection/components/ai-avatar/ai-avatar.js +1 -1
  80. package/dist/collection/components/badge/badge.js +2 -2
  81. package/dist/collection/components/banner/banner.js +1 -1
  82. package/dist/collection/components/breadcrumbs/breadcrumbs.js +1 -1
  83. package/dist/collection/components/button/button.js +2 -2
  84. package/dist/collection/components/button-group/button-group.js +1 -1
  85. package/dist/collection/components/callout/callout.js +1 -1
  86. package/dist/collection/components/card/card.js +1 -1
  87. package/dist/collection/components/checkbox/checkbox.js +1 -1
  88. package/dist/collection/components/chip/chip.js +11 -7
  89. package/dist/collection/components/chip-set/chip-set.js +1 -1
  90. package/dist/collection/components/circular-progress/circular-progress.js +2 -2
  91. package/dist/collection/components/code-diff/code-diff.js +1 -1
  92. package/dist/collection/components/code-editor/code-editor.js +1 -1
  93. package/dist/collection/components/collapsible-section/collapsible-section.js +1 -1
  94. package/dist/collection/components/color-picker/color-picker-palette.js +2 -2
  95. package/dist/collection/components/color-picker/color-picker.js +1 -1
  96. package/dist/collection/components/date-picker/flatpickr-adapter/flatpickr-adapter.js +1 -1
  97. package/dist/collection/components/dialog/dialog.js +2 -2
  98. package/dist/collection/components/dock/dock.js +3 -3
  99. package/dist/collection/components/drag-handle/drag-handle.js +1 -1
  100. package/dist/collection/components/email-viewer/email-viewer.js +1 -1
  101. package/dist/collection/components/file/file.js +1 -1
  102. package/dist/collection/components/file-dropzone/file-dropzone.js +1 -1
  103. package/dist/collection/components/file-input/file-input.js +1 -1
  104. package/dist/collection/components/flex-container/flex-container.js +1 -1
  105. package/dist/collection/components/form/form.js +1 -1
  106. package/dist/collection/components/grid/grid.js +1 -1
  107. package/dist/collection/components/header/header.js +1 -1
  108. package/dist/collection/components/help/help-content.js +1 -1
  109. package/dist/collection/components/help/help.js +2 -2
  110. package/dist/collection/components/helper-line/helper-line.js +2 -2
  111. package/dist/collection/components/hotkey/hotkey.js +1 -1
  112. package/dist/collection/components/icon/icon.js +1 -1
  113. package/dist/collection/components/icon-button/icon-button.js +1 -1
  114. package/dist/collection/components/info-tile/info-tile.js +2 -2
  115. package/dist/collection/components/input-field/input-field.js +1 -1
  116. package/dist/collection/components/list/list.js +1 -1
  117. package/dist/collection/components/list-item/list-item.js +2 -2
  118. package/dist/collection/components/list-item/menu-item-meta/menu-item-meta.js +1 -1
  119. package/dist/collection/components/markdown/markdown-parser.js +31 -4
  120. package/dist/collection/components/markdown/markdown.js +2 -1
  121. package/dist/collection/components/masonry-layout/masonry-layout.js +1 -1
  122. package/dist/collection/components/menu/menu.js +2 -2
  123. package/dist/collection/components/menu-list/menu-list.js +1 -1
  124. package/dist/collection/components/menu-surface/menu-surface.js +1 -1
  125. package/dist/collection/components/notched-outline/notched-outline.js +1 -1
  126. package/dist/collection/components/picker/picker.js +1 -1
  127. package/dist/collection/components/popover/popover.js +1 -1
  128. package/dist/collection/components/popover-surface/popover-surface.js +1 -1
  129. package/dist/collection/components/portal/portal.js +1 -1
  130. package/dist/collection/components/radio-button-group/radio-button-group.js +1 -1
  131. package/dist/collection/components/radio-button-group/radio-button.js +2 -2
  132. package/dist/collection/components/select/select.js +1 -1
  133. package/dist/collection/components/shortcut/shortcut.js +1 -1
  134. package/dist/collection/components/slider/slider.js +5 -5
  135. package/dist/collection/components/snackbar/snackbar.js +2 -2
  136. package/dist/collection/components/spinner/spinner.js +1 -1
  137. package/dist/collection/components/split-button/split-button.js +2 -2
  138. package/dist/collection/components/switch/switch.js +1 -1
  139. package/dist/collection/components/tab-bar/tab-bar.js +2 -2
  140. package/dist/collection/components/tab-panel/tab-panel.js +1 -1
  141. package/dist/collection/components/table/table.css +1 -0
  142. package/dist/collection/components/table/table.js +3 -3
  143. package/dist/collection/components/text-editor/link-menu/editor-link-menu.js +3 -3
  144. package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js +1 -1
  145. package/dist/collection/components/text-editor/text-editor.js +1 -1
  146. package/dist/collection/components/tooltip/tooltip-content.js +1 -1
  147. package/dist/collection/components/tooltip/tooltip.js +3 -3
  148. package/dist/esm/{checkbox.template-CfWJ3CAC.js → checkbox.template-CtIjSGPt.js} +1 -1
  149. package/dist/esm/{index-t4DgGbWS.js → index-CbciMfiU.js} +10 -1
  150. package/dist/esm/{index-DBTJNfo7.js → index-VCOjLfyP.js} +57 -21
  151. package/dist/esm/lime-elements.js +3 -3
  152. package/dist/esm/limel-3d-hover-effect-glow.entry.js +2 -2
  153. package/dist/esm/limel-action-bar_3.entry.js +4 -4
  154. package/dist/esm/limel-ai-avatar.entry.js +2 -2
  155. package/dist/esm/limel-badge.entry.js +3 -3
  156. package/dist/esm/limel-banner.entry.js +2 -2
  157. package/dist/esm/limel-breadcrumbs_8.entry.js +9 -9
  158. package/dist/esm/limel-button-group.entry.js +2 -2
  159. package/dist/esm/limel-button.entry.js +3 -3
  160. package/dist/esm/limel-callout.entry.js +2 -2
  161. package/dist/esm/limel-card.entry.js +2 -2
  162. package/dist/esm/limel-chart.entry.js +1 -1
  163. package/dist/esm/limel-checkbox.entry.js +3 -3
  164. package/dist/esm/limel-chip-set.entry.js +2 -2
  165. package/dist/esm/limel-chip_2.entry.js +2 -2
  166. package/dist/esm/limel-circular-progress.entry.js +2 -2
  167. package/dist/esm/limel-code-diff.entry.js +75 -34
  168. package/dist/esm/limel-code-editor.entry.js +2 -2
  169. package/dist/esm/limel-collapsible-section.entry.js +2 -2
  170. package/dist/esm/limel-color-picker-palette.entry.js +3 -3
  171. package/dist/esm/limel-color-picker.entry.js +2 -2
  172. package/dist/esm/limel-config.entry.js +1 -1
  173. package/dist/esm/limel-date-picker.entry.js +1 -1
  174. package/dist/esm/limel-dialog.entry.js +3 -3
  175. package/dist/esm/limel-dock-button.entry.js +1 -1
  176. package/dist/esm/limel-dock.entry.js +3 -3
  177. package/dist/esm/limel-drag-handle.entry.js +2 -2
  178. package/dist/esm/limel-dynamic-label.entry.js +1 -1
  179. package/dist/esm/limel-email-viewer.entry.js +2 -2
  180. package/dist/esm/limel-file-dropzone_2.entry.js +3 -3
  181. package/dist/esm/limel-file-viewer.entry.js +62 -50
  182. package/dist/esm/limel-file.entry.js +2 -2
  183. package/dist/esm/limel-flatpickr-adapter.entry.js +2 -2
  184. package/dist/esm/limel-flex-container.entry.js +2 -2
  185. package/dist/esm/limel-form.entry.js +7831 -6820
  186. package/dist/esm/limel-grid.entry.js +2 -2
  187. package/dist/esm/limel-header.entry.js +2 -2
  188. package/dist/esm/limel-help-content.entry.js +2 -2
  189. package/dist/esm/limel-help.entry.js +3 -3
  190. package/dist/esm/limel-helper-line.entry.js +3 -3
  191. package/dist/esm/limel-hotkey_4.entry.js +6 -6
  192. package/dist/esm/limel-icon-button.entry.js +2 -2
  193. package/dist/esm/limel-icon.entry.js +2 -2
  194. package/dist/esm/limel-info-tile.entry.js +3 -3
  195. package/dist/esm/limel-list-item.entry.js +5 -5
  196. package/dist/esm/limel-markdown.entry.js +4 -4
  197. package/dist/esm/limel-masonry-layout.entry.js +2 -2
  198. package/dist/esm/limel-menu-item-meta.entry.js +2 -2
  199. package/dist/esm/limel-picker.entry.js +2 -2
  200. package/dist/esm/limel-popover_2.entry.js +3 -3
  201. package/dist/esm/limel-profile-picture.entry.js +1 -1
  202. package/dist/esm/limel-progress-flow-item.entry.js +1 -1
  203. package/dist/esm/limel-progress-flow.entry.js +1 -1
  204. package/dist/esm/limel-prosemirror-adapter.entry.js +1833 -1639
  205. package/dist/esm/limel-radio-button-group.entry.js +2 -2
  206. package/dist/esm/limel-radio-button.entry.js +3 -3
  207. package/dist/esm/limel-select.entry.js +3 -3
  208. package/dist/esm/limel-shortcut.entry.js +2 -2
  209. package/dist/esm/limel-slider.entry.js +3 -3
  210. package/dist/esm/limel-snackbar.entry.js +3 -3
  211. package/dist/esm/limel-split-button.entry.js +3 -3
  212. package/dist/esm/limel-switch.entry.js +2 -2
  213. package/dist/esm/limel-tab-bar.entry.js +3 -3
  214. package/dist/esm/limel-tab-panel.entry.js +2 -2
  215. package/dist/esm/limel-table.entry.js +255 -154
  216. package/dist/esm/limel-text-editor-link-menu.entry.js +4 -4
  217. package/dist/esm/limel-text-editor.entry.js +2 -2
  218. package/dist/esm/loader.js +2 -2
  219. package/dist/esm/{markdown-parser-D7vLKElE.js → markdown-parser-Blt6ZFY0.js} +326 -333
  220. package/dist/esm/{render-list-component-D7LjGxDF.js → render-list-component-BdncB2vG.js} +1 -1
  221. package/dist/lime-elements/lime-elements.esm.js +1 -1
  222. package/dist/lime-elements/{p-1efd78ee.entry.js → p-0605c490.entry.js} +1 -1
  223. package/dist/lime-elements/{p-5d9adcbb.entry.js → p-08e7006f.entry.js} +1 -1
  224. package/dist/lime-elements/p-0b9f3cf1.entry.js +1 -0
  225. package/dist/lime-elements/p-10955e5d.entry.js +1 -0
  226. package/dist/lime-elements/p-1153e2ba.entry.js +1 -0
  227. package/dist/lime-elements/{p-49901dd7.entry.js → p-17ff8353.entry.js} +1 -1
  228. package/dist/lime-elements/p-2486f61d.entry.js +1 -0
  229. package/dist/lime-elements/{p-19a259ff.entry.js → p-2a27bf12.entry.js} +1 -1
  230. package/dist/lime-elements/{p-d8b640e8.entry.js → p-2cb55d62.entry.js} +1 -1
  231. package/dist/lime-elements/{p-0f8672fe.entry.js → p-2ef433e0.entry.js} +1 -1
  232. package/dist/lime-elements/{p-12aa0d06.entry.js → p-317d56a7.entry.js} +1 -1
  233. package/dist/lime-elements/{p-d5f189b9.entry.js → p-31965f6c.entry.js} +2 -2
  234. package/dist/lime-elements/{p-61ec46d5.entry.js → p-33ab319b.entry.js} +1 -1
  235. package/dist/lime-elements/p-444e3088.entry.js +1 -0
  236. package/dist/lime-elements/{p-4a9b5914.entry.js → p-44bd59ac.entry.js} +1 -1
  237. package/dist/lime-elements/{p-5f121609.entry.js → p-45801616.entry.js} +1 -1
  238. package/dist/lime-elements/{p-1ae8b33a.entry.js → p-53b7bee8.entry.js} +1 -1
  239. package/dist/lime-elements/{p-08a261ce.entry.js → p-5a00f0fb.entry.js} +1 -1
  240. package/dist/lime-elements/{p-122cd39d.entry.js → p-66600fc3.entry.js} +1 -1
  241. package/dist/lime-elements/{p-46900c5b.entry.js → p-6c60d915.entry.js} +1 -1
  242. package/dist/lime-elements/{p-a85b2734.entry.js → p-6fa4b1b3.entry.js} +1 -1
  243. package/dist/lime-elements/{p-59716b48.entry.js → p-719dc4c0.entry.js} +1 -1
  244. package/dist/lime-elements/{p-7b074737.entry.js → p-7776313e.entry.js} +1 -1
  245. package/dist/lime-elements/{p-6ca1da96.entry.js → p-7b687fc6.entry.js} +1 -1
  246. package/dist/lime-elements/{p-2a92790c.entry.js → p-7f891de4.entry.js} +1 -1
  247. package/dist/lime-elements/{p-a7764b6d.entry.js → p-80b0bcb3.entry.js} +1 -1
  248. package/dist/lime-elements/{p-871eb795.entry.js → p-8376ac0d.entry.js} +2 -2
  249. package/dist/lime-elements/{p-dee5717c.entry.js → p-8aaf4f50.entry.js} +1 -1
  250. package/dist/lime-elements/{p-8fde4714.entry.js → p-90a506aa.entry.js} +1 -1
  251. package/dist/lime-elements/{p-d0288858.entry.js → p-9b7966f1.entry.js} +1 -1
  252. package/dist/lime-elements/{p-bffbd011.entry.js → p-9bb07225.entry.js} +1 -1
  253. package/dist/lime-elements/{p-a6805c64.entry.js → p-9e8eaa86.entry.js} +1 -1
  254. package/dist/lime-elements/{p-989f4a52.entry.js → p-9eb06bf7.entry.js} +1 -1
  255. package/dist/lime-elements/{p-faceccc0.entry.js → p-9eb6879d.entry.js} +1 -1
  256. package/dist/lime-elements/{p--9pvUs5M.js → p-D9twpDvz.js} +1 -1
  257. package/dist/lime-elements/p-DMNtoJ8I.js +1 -0
  258. package/dist/lime-elements/{p-DdYOzHlg.js → p-DnPeu2SH.js} +2 -2
  259. package/dist/lime-elements/p-NN0EYecx.js +1 -0
  260. package/dist/lime-elements/p-VCOjLfyP.js +2 -0
  261. package/dist/lime-elements/{p-e5e8a734.entry.js → p-a0720aca.entry.js} +8 -8
  262. package/dist/lime-elements/{p-f5d60f9c.entry.js → p-a11abcb0.entry.js} +4 -4
  263. package/dist/lime-elements/p-a73f70d7.entry.js +1 -0
  264. package/dist/lime-elements/{p-129a19c7.entry.js → p-a7e9e96c.entry.js} +1 -1
  265. package/dist/lime-elements/{p-140afd9f.entry.js → p-a827a280.entry.js} +1 -1
  266. package/dist/lime-elements/{p-d0607ba8.entry.js → p-aa6190e8.entry.js} +1 -1
  267. package/dist/lime-elements/{p-b8a31121.entry.js → p-aa8d7faa.entry.js} +1 -1
  268. package/dist/lime-elements/{p-5da0315f.entry.js → p-aba01020.entry.js} +1 -1
  269. package/dist/lime-elements/{p-b61a1d27.entry.js → p-ac5d5099.entry.js} +2 -2
  270. package/dist/lime-elements/{p-9b3e8f43.entry.js → p-b3b53dbc.entry.js} +1 -1
  271. package/dist/lime-elements/{p-9359e870.entry.js → p-b7649589.entry.js} +1 -1
  272. package/dist/lime-elements/{p-1a5541f1.entry.js → p-bcc2cb1a.entry.js} +1 -1
  273. package/dist/lime-elements/{p-4d948ed5.entry.js → p-c447d311.entry.js} +1 -1
  274. package/dist/lime-elements/{p-33bd5212.entry.js → p-c6cbd842.entry.js} +1 -1
  275. package/dist/lime-elements/{p-df0b927e.entry.js → p-caf1bca2.entry.js} +1 -1
  276. package/dist/lime-elements/{p-f85dbaec.entry.js → p-cdbab1d5.entry.js} +1 -1
  277. package/dist/lime-elements/p-d8d6e12a.entry.js +13 -0
  278. package/dist/lime-elements/{p-60518e6b.entry.js → p-db0bd965.entry.js} +1 -1
  279. package/dist/lime-elements/{p-22f34040.entry.js → p-dc415221.entry.js} +1 -1
  280. package/dist/lime-elements/{p-91990c64.entry.js → p-e31d0b36.entry.js} +1 -1
  281. package/dist/lime-elements/p-e38a13fb.entry.js +1 -0
  282. package/dist/lime-elements/{p-fa0d7b8c.entry.js → p-e4549e8b.entry.js} +1 -1
  283. package/dist/lime-elements/{p-d09e74b1.entry.js → p-e59d7177.entry.js} +1 -1
  284. package/dist/lime-elements/{p-50f51eb9.entry.js → p-e7b9716f.entry.js} +1 -1
  285. package/dist/lime-elements/{p-9e1a4d63.entry.js → p-ed70059b.entry.js} +1 -1
  286. package/dist/lime-elements/{p-afd4be62.entry.js → p-eef0cd8b.entry.js} +1 -1
  287. package/dist/lime-elements/{p-de203f64.entry.js → p-f7695614.entry.js} +1 -1
  288. package/dist/lime-elements/{p-198f3179.entry.js → p-f91de6bd.entry.js} +1 -1
  289. package/dist/lime-elements/{p-2a9e7bf5.entry.js → p-f9b74b03.entry.js} +1 -1
  290. package/dist/lime-elements/{p-6b7e58c3.entry.js → p-fac02bae.entry.js} +1 -1
  291. package/dist/lime-elements/{p-82fb5c74.entry.js → p-fc435802.entry.js} +1 -1
  292. package/dist/lime-elements/p-fe64b285.entry.js +1 -0
  293. package/dist/types/components/form/widgets/code-editor.d.ts +2 -2
  294. package/dist/types/components/markdown/markdown.d.ts +1 -0
  295. package/dist/types/components.d.ts +26 -20
  296. package/dist/types/stencil-public-runtime.d.ts +1 -0
  297. package/package.json +34 -36
  298. package/dist/lime-elements/p-00e54ccf.entry.js +0 -1
  299. package/dist/lime-elements/p-1614ad86.entry.js +0 -1
  300. package/dist/lime-elements/p-16254e4a.entry.js +0 -1
  301. package/dist/lime-elements/p-3f78362b.entry.js +0 -13
  302. package/dist/lime-elements/p-5b9d84b4.entry.js +0 -1
  303. package/dist/lime-elements/p-6015621e.entry.js +0 -1
  304. package/dist/lime-elements/p-730ba357.entry.js +0 -1
  305. package/dist/lime-elements/p-84f5727c.entry.js +0 -1
  306. package/dist/lime-elements/p-BaPK7VfG.js +0 -1
  307. package/dist/lime-elements/p-DBTJNfo7.js +0 -2
  308. package/dist/lime-elements/p-DJvGLFul.js +0 -1
  309. package/dist/lime-elements/p-c9fa7a09.entry.js +0 -1
@@ -1,8 +1,8 @@
1
- import { r as registerInstance, c as createEvent, h, H as Host, a as getElement } from './index-DBTJNfo7.js';
1
+ import { r as registerInstance, c as createEvent, h, H as Host, a as getElement } from './index-VCOjLfyP.js';
2
2
  import { E as EditorMenuTypes, L as LevelMapping, M as MouseButtons, e as editorMenuTypesArray } from './types-BWYo6dLf.js';
3
- import { g as getLinkAttributes, m as markdownToHTML, s as sanitizeHTML } from './markdown-parser-D7vLKElE.js';
3
+ import { g as getLinkAttributes, m as markdownToHTML, s as sanitizeHTML } from './markdown-parser-Blt6ZFY0.js';
4
4
  import { h as cloneDeep } from './cloneDeep-CL7UD3mR.js';
5
- import { c as decodeHTML } from './index-t4DgGbWS.js';
5
+ import { c as decodeHTML, e as decodeHTMLStrict } from './index-CbciMfiU.js';
6
6
  import { t as translate } from './translations-EPnIW0K5.js';
7
7
  import { c as createRandomString } from './random-string-JbKhhoXs.js';
8
8
  import { i as isItem } from './is-item-CrvUOVvg.js';
@@ -233,7 +233,7 @@ class Fragment {
233
233
  */
234
234
  constructor(
235
235
  /**
236
- @internal
236
+ The child nodes in this fragment.
237
237
  */
238
238
  content, size) {
239
239
  this.content = content;
@@ -437,7 +437,7 @@ class Fragment {
437
437
  position in this fragment. The result object will be reused
438
438
  (overwritten) the next time the function is called. @internal
439
439
  */
440
- findIndex(pos, round = -1) {
440
+ findIndex(pos) {
441
441
  if (pos == 0)
442
442
  return retIndex(0, pos);
443
443
  if (pos == this.size)
@@ -447,7 +447,7 @@ class Fragment {
447
447
  for (let i = 0, curPos = 0;; i++) {
448
448
  let cur = this.child(i), end = curPos + cur.nodeSize;
449
449
  if (end >= pos) {
450
- if (end == pos || round > 0)
450
+ if (end == pos)
451
451
  return retIndex(i + 1, end);
452
452
  return retIndex(i, curPos);
453
453
  }
@@ -476,7 +476,7 @@ class Fragment {
476
476
  return Fragment.empty;
477
477
  if (!Array.isArray(value))
478
478
  throw new RangeError("Invalid input for Fragment.fromJSON");
479
- return new Fragment(value.map(schema.nodeFromJSON));
479
+ return Fragment.fromArray(value.map(schema.nodeFromJSON));
480
480
  }
481
481
  /**
482
482
  Build a fragment from an array of nodes. Ensures that adjacent
@@ -710,17 +710,6 @@ given an invalid replacement.
710
710
  */
711
711
  class ReplaceError extends Error {
712
712
  }
713
- /*
714
- ReplaceError = function(this: any, message: string) {
715
- let err = Error.call(this, message)
716
- ;(err as any).__proto__ = ReplaceError.prototype
717
- return err
718
- } as any
719
-
720
- ReplaceError.prototype = Object.create(Error.prototype)
721
- ReplaceError.prototype.constructor = ReplaceError
722
- ReplaceError.prototype.name = "ReplaceError"
723
- */
724
713
  /**
725
714
  A slice represents a piece cut out of a larger document. It
726
715
  stores not only a fragment, but also the depth up to which nodes on
@@ -766,7 +755,7 @@ class Slice {
766
755
  @internal
767
756
  */
768
757
  insertAt(pos, fragment) {
769
- let content = insertInto(this.content, pos + this.openStart, fragment);
758
+ let content = insertInto(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1);
770
759
  return content && new Slice(content, this.openStart, this.openEnd);
771
760
  }
772
761
  /**
@@ -840,12 +829,14 @@ function removeRange(content, from, to) {
840
829
  throw new RangeError("Removing non-flat range");
841
830
  return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1)));
842
831
  }
843
- function insertInto(content, dist, insert, parent) {
832
+ function insertInto(content, dist, insert, openStart, openEnd, parent) {
844
833
  let { index, offset } = content.findIndex(dist), child = content.maybeChild(index);
845
834
  if (offset == dist || child.isText) {
835
+ if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert))
836
+ return null;
846
837
  return content.cut(0, dist).append(insert).append(content.cut(dist));
847
838
  }
848
- let inner = insertInto(child.content, dist - offset - 1, insert);
839
+ let inner = insertInto(child.content, dist - offset - 1, insert, index == 0 ? openStart - 1 : 0, index == content.childCount - 1 ? openEnd - 1 : 0, child);
849
840
  return inner && content.replaceChild(index, child.copy(inner));
850
841
  }
851
842
  function replace$1($from, $to, slice) {
@@ -1315,7 +1306,7 @@ structure between the old and new data as much as possible, which a
1315
1306
  tree shape like this (without back pointers) makes easy.
1316
1307
 
1317
1308
  **Do not** directly mutate the properties of a `Node` object. See
1318
- [the guide](/docs/guide/#doc) for more information.
1309
+ [the guide](https://prosemirror.net/docs/guide/#doc) for more information.
1319
1310
  */
1320
1311
  class Node {
1321
1312
  /**
@@ -1345,8 +1336,12 @@ class Node {
1345
1336
  this.content = content || Fragment.empty;
1346
1337
  }
1347
1338
  /**
1339
+ The array of this node's child nodes.
1340
+ */
1341
+ get children() { return this.content.content; }
1342
+ /**
1348
1343
  The size of this node, as defined by the integer-based [indexing
1349
- scheme](/docs/guide/#doc.indexing). For text nodes, this is the
1344
+ scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the
1350
1345
  amount of characters. For other leaf nodes, it is one. For
1351
1346
  non-leaf nodes, it is the size of the content plus two (the
1352
1347
  start and end token).
@@ -1371,10 +1366,11 @@ class Node {
1371
1366
  */
1372
1367
  forEach(f) { this.content.forEach(f); }
1373
1368
  /**
1374
- Invoke a callback for all descendant nodes recursively between
1369
+ Invoke a callback for all descendant nodes recursively overlapping
1375
1370
  the given two positions that are relative to start of this
1376
- node's content. The callback is invoked with the node, its
1377
- position relative to the original node (method receiver),
1371
+ node's content. This includes all ancestors of the nodes
1372
+ containing the two positions. The callback is invoked with the
1373
+ node, its position relative to the original node (method receiver),
1378
1374
  its parent node, and its child index. When the callback returns
1379
1375
  false for a given node, that node's children will not be
1380
1376
  recursed over. The last parameter can be used to specify a
@@ -1404,7 +1400,7 @@ class Node {
1404
1400
  `blockSeparator` is given, it will be inserted to separate text
1405
1401
  from different block nodes. If `leafText` is given, it'll be
1406
1402
  inserted for every non-text leaf node encountered, otherwise
1407
- [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec^leafText) will be used.
1403
+ [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used.
1408
1404
  */
1409
1405
  textBetween(from, to, blockSeparator, leafText) {
1410
1406
  return this.content.textBetween(from, to, blockSeparator, leafText);
@@ -2011,7 +2007,7 @@ function resolveName(stream, name) {
2011
2007
  let result = [];
2012
2008
  for (let typeName in types) {
2013
2009
  let type = types[typeName];
2014
- if (type.groups.indexOf(name) > -1)
2010
+ if (type.isInGroup(name))
2015
2011
  result.push(type);
2016
2012
  }
2017
2013
  if (result.length == 0)
@@ -2040,16 +2036,14 @@ function parseExprAtom(stream) {
2040
2036
  stream.err("Unexpected token '" + stream.next + "'");
2041
2037
  }
2042
2038
  }
2043
- /**
2044
- Construct an NFA from an expression as returned by the parser. The
2045
- NFA is represented as an array of states, which are themselves
2046
- arrays of edges, which are `{term, to}` objects. The first state is
2047
- the entry state and the last node is the success state.
2048
-
2049
- Note that unlike typical NFAs, the edge ordering in this one is
2050
- significant, in that it is used to contruct filler content when
2051
- necessary.
2052
- */
2039
+ // Construct an NFA from an expression as returned by the parser. The
2040
+ // NFA is represented as an array of states, which are themselves
2041
+ // arrays of edges, which are `{term, to}` objects. The first state is
2042
+ // the entry state and the last node is the success state.
2043
+ //
2044
+ // Note that unlike typical NFAs, the edge ordering in this one is
2045
+ // significant, in that it is used to contruct filler content when
2046
+ // necessary.
2053
2047
  function nfa(expr) {
2054
2048
  let nfa = [[]];
2055
2049
  connect(compile(expr, 0), node());
@@ -2290,6 +2284,13 @@ let NodeType$1 = class NodeType {
2290
2284
  */
2291
2285
  get isAtom() { return this.isLeaf || !!this.spec.atom; }
2292
2286
  /**
2287
+ Return true when this node type is part of the given
2288
+ [group](https://prosemirror.net/docs/ref/#model.NodeSpec.group).
2289
+ */
2290
+ isInGroup(group) {
2291
+ return this.groups.indexOf(group) > -1;
2292
+ }
2293
+ /**
2293
2294
  The node type's [whitespace](https://prosemirror.net/docs/ref/#model.NodeSpec.whitespace) option.
2294
2295
  */
2295
2296
  get whitespace() {
@@ -2609,8 +2610,8 @@ class Schema {
2609
2610
  let type = this.marks[prop], excl = type.spec.excludes;
2610
2611
  type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" "));
2611
2612
  }
2612
- this.nodeFromJSON = this.nodeFromJSON.bind(this);
2613
- this.markFromJSON = this.markFromJSON.bind(this);
2613
+ this.nodeFromJSON = json => Node.fromJSON(this, json);
2614
+ this.markFromJSON = json => Mark.fromJSON(this, json);
2614
2615
  this.topNodeType = this.nodes[this.spec.topNode || "doc"];
2615
2616
  this.cached.wrappings = Object.create(null);
2616
2617
  }
@@ -2646,20 +2647,6 @@ class Schema {
2646
2647
  return type.create(attrs);
2647
2648
  }
2648
2649
  /**
2649
- Deserialize a node from its JSON representation. This method is
2650
- bound.
2651
- */
2652
- nodeFromJSON(json) {
2653
- return Node.fromJSON(this, json);
2654
- }
2655
- /**
2656
- Deserialize a mark from its JSON representation. This method is
2657
- bound.
2658
- */
2659
- markFromJSON(json) {
2660
- return Mark.fromJSON(this, json);
2661
- }
2662
- /**
2663
2650
  @internal
2664
2651
  */
2665
2652
  nodeType(name) {
@@ -2841,7 +2828,7 @@ class DOMParser {
2841
2828
  /**
2842
2829
  Construct a DOM parser using the parsing rules listed in a
2843
2830
  schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by
2844
- [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority).
2831
+ [priority](https://prosemirror.net/docs/ref/#model.GenericParseRule.priority).
2845
2832
  */
2846
2833
  static fromSchema(schema) {
2847
2834
  return schema.cached.domParser ||
@@ -2934,6 +2921,7 @@ class ParseContext {
2934
2921
  this.options = options;
2935
2922
  this.isOpen = isOpen;
2936
2923
  this.open = 0;
2924
+ this.localPreserveWS = false;
2937
2925
  let topNode = options.topNode, topContext;
2938
2926
  let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0);
2939
2927
  if (topNode)
@@ -2960,11 +2948,13 @@ class ParseContext {
2960
2948
  }
2961
2949
  addTextNode(dom, marks) {
2962
2950
  let value = dom.nodeValue;
2963
- let top = this.top;
2964
- if (top.options & OPT_PRESERVE_WS_FULL ||
2951
+ let top = this.top, preserveWS = (top.options & OPT_PRESERVE_WS_FULL) ? "full"
2952
+ : this.localPreserveWS || (top.options & OPT_PRESERVE_WS) > 0;
2953
+ let { schema } = this.parser;
2954
+ if (preserveWS === "full" ||
2965
2955
  top.inlineContext(dom) ||
2966
2956
  /[^ \t\r\n\u000c]/.test(value)) {
2967
- if (!(top.options & OPT_PRESERVE_WS)) {
2957
+ if (!preserveWS) {
2968
2958
  value = value.replace(/[ \t\r\n\u000c]+/g, " ");
2969
2959
  // If this starts with whitespace, and there is no node before it, or
2970
2960
  // a hard break, or a text node that ends with whitespace, strip the
@@ -2978,14 +2968,24 @@ class ParseContext {
2978
2968
  value = value.slice(1);
2979
2969
  }
2980
2970
  }
2981
- else if (!(top.options & OPT_PRESERVE_WS_FULL)) {
2982
- value = value.replace(/\r?\n|\r/g, " ");
2971
+ else if (preserveWS === "full") {
2972
+ value = value.replace(/\r\n?/g, "\n");
2973
+ }
2974
+ else if (schema.linebreakReplacement && /[\r\n]/.test(value) && this.top.findWrapping(schema.linebreakReplacement.create())) {
2975
+ let lines = value.split(/\r?\n|\r/);
2976
+ for (let i = 0; i < lines.length; i++) {
2977
+ if (i)
2978
+ this.insertNode(schema.linebreakReplacement.create(), marks, true);
2979
+ if (lines[i])
2980
+ this.insertNode(schema.text(lines[i]), marks, !/\S/.test(lines[i]));
2981
+ }
2982
+ value = "";
2983
2983
  }
2984
2984
  else {
2985
- value = value.replace(/\r\n?/g, "\n");
2985
+ value = value.replace(/\r?\n|\r/g, " ");
2986
2986
  }
2987
2987
  if (value)
2988
- this.insertNode(this.parser.schema.text(value), marks);
2988
+ this.insertNode(schema.text(value), marks, !/\S/.test(value));
2989
2989
  this.findInText(dom);
2990
2990
  }
2991
2991
  else {
@@ -2995,12 +2995,15 @@ class ParseContext {
2995
2995
  // Try to find a handler for the given tag and use that to parse. If
2996
2996
  // none is found, the element's content nodes are added directly.
2997
2997
  addElement(dom, marks, matchAfter) {
2998
+ let outerWS = this.localPreserveWS, top = this.top;
2999
+ if (dom.tagName == "PRE" || /pre/.test(dom.style && dom.style.whiteSpace))
3000
+ this.localPreserveWS = true;
2998
3001
  let name = dom.nodeName.toLowerCase(), ruleID;
2999
3002
  if (listTags.hasOwnProperty(name) && this.parser.normalizeLists)
3000
3003
  normalizeList(dom);
3001
3004
  let rule = (this.options.ruleFromNode && this.options.ruleFromNode(dom)) ||
3002
3005
  (ruleID = this.parser.matchTag(dom, this, matchAfter));
3003
- if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
3006
+ out: if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
3004
3007
  this.findInside(dom);
3005
3008
  this.ignoreFallback(dom, marks);
3006
3009
  }
@@ -3009,7 +3012,7 @@ class ParseContext {
3009
3012
  this.open = Math.max(0, this.open - 1);
3010
3013
  else if (rule && rule.skip.nodeType)
3011
3014
  dom = rule.skip;
3012
- let sync, top = this.top, oldNeedsBlock = this.needsBlock;
3015
+ let sync, oldNeedsBlock = this.needsBlock;
3013
3016
  if (blockTags.hasOwnProperty(name)) {
3014
3017
  if (top.content.length && top.content[0].isInline && this.open) {
3015
3018
  this.open--;
@@ -3021,7 +3024,7 @@ class ParseContext {
3021
3024
  }
3022
3025
  else if (!dom.firstChild) {
3023
3026
  this.leafFallback(dom, marks);
3024
- return;
3027
+ break out;
3025
3028
  }
3026
3029
  let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks);
3027
3030
  if (innerMarks)
@@ -3035,6 +3038,7 @@ class ParseContext {
3035
3038
  if (innerMarks)
3036
3039
  this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : undefined);
3037
3040
  }
3041
+ this.localPreserveWS = outerWS;
3038
3042
  }
3039
3043
  // Called for leaf DOM nodes that would otherwise be ignored
3040
3044
  leafFallback(dom, marks) {
@@ -3045,7 +3049,7 @@ class ParseContext {
3045
3049
  ignoreFallback(dom, marks) {
3046
3050
  // Ignored BR nodes should at least create an inline context
3047
3051
  if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent))
3048
- this.findPlace(this.parser.schema.text("-"), marks);
3052
+ this.findPlace(this.parser.schema.text("-"), marks, true);
3049
3053
  }
3050
3054
  // Run any style parser associated with the node's styles. Either
3051
3055
  // return an updated array of marks, or null to indicate some of the
@@ -3093,7 +3097,7 @@ class ParseContext {
3093
3097
  marks = inner;
3094
3098
  }
3095
3099
  }
3096
- else if (!this.insertNode(nodeType.create(rule.attrs), marks)) {
3100
+ else if (!this.insertNode(nodeType.create(rule.attrs), marks, dom.nodeName == "BR")) {
3097
3101
  this.leafFallback(dom, marks);
3098
3102
  }
3099
3103
  }
@@ -3110,7 +3114,7 @@ class ParseContext {
3110
3114
  }
3111
3115
  else if (rule.getContent) {
3112
3116
  this.findInside(dom);
3113
- rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks));
3117
+ rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks, false));
3114
3118
  }
3115
3119
  else {
3116
3120
  let contentDOM = dom;
@@ -3122,6 +3126,7 @@ class ParseContext {
3122
3126
  contentDOM = rule.contentElement;
3123
3127
  this.findAround(dom, contentDOM, true);
3124
3128
  this.addAll(contentDOM, marks);
3129
+ this.findAround(dom, contentDOM, false);
3125
3130
  }
3126
3131
  if (sync && this.sync(startIn))
3127
3132
  this.open--;
@@ -3140,19 +3145,22 @@ class ParseContext {
3140
3145
  // Try to find a way to fit the given node type into the current
3141
3146
  // context. May add intermediate wrappers and/or leave non-solid
3142
3147
  // nodes that we're in.
3143
- findPlace(node, marks) {
3148
+ findPlace(node, marks, cautious) {
3144
3149
  let route, sync;
3145
- for (let depth = this.open; depth >= 0; depth--) {
3150
+ for (let depth = this.open, penalty = 0; depth >= 0; depth--) {
3146
3151
  let cx = this.nodes[depth];
3147
3152
  let found = cx.findWrapping(node);
3148
- if (found && (!route || route.length > found.length)) {
3153
+ if (found && (!route || route.length > found.length + penalty)) {
3149
3154
  route = found;
3150
3155
  sync = cx;
3151
3156
  if (!found.length)
3152
3157
  break;
3153
3158
  }
3154
- if (cx.solid)
3155
- break;
3159
+ if (cx.solid) {
3160
+ if (cautious)
3161
+ break;
3162
+ penalty += 2;
3163
+ }
3156
3164
  }
3157
3165
  if (!route)
3158
3166
  return null;
@@ -3162,13 +3170,13 @@ class ParseContext {
3162
3170
  return marks;
3163
3171
  }
3164
3172
  // Try to insert the given node, adjusting the context when needed.
3165
- insertNode(node, marks) {
3173
+ insertNode(node, marks, cautious) {
3166
3174
  if (node.isInline && this.needsBlock && !this.top.type) {
3167
3175
  let block = this.textblockFromContext();
3168
3176
  if (block)
3169
3177
  marks = this.enterInner(block, null, marks);
3170
3178
  }
3171
- let innerMarks = this.findPlace(node, marks);
3179
+ let innerMarks = this.findPlace(node, marks, cautious);
3172
3180
  if (innerMarks) {
3173
3181
  this.closeExtra();
3174
3182
  let top = this.top;
@@ -3186,7 +3194,7 @@ class ParseContext {
3186
3194
  // Try to start a node of the given type, adjusting the context when
3187
3195
  // necessary.
3188
3196
  enter(type, attrs, marks, preserveWS) {
3189
- let innerMarks = this.findPlace(type.create(attrs), marks);
3197
+ let innerMarks = this.findPlace(type.create(attrs), marks, false);
3190
3198
  if (innerMarks)
3191
3199
  innerMarks = this.enterInner(type, attrs, marks, true, preserveWS);
3192
3200
  return innerMarks;
@@ -3224,14 +3232,18 @@ class ParseContext {
3224
3232
  finish() {
3225
3233
  this.open = 0;
3226
3234
  this.closeExtra(this.isOpen);
3227
- return this.nodes[0].finish(this.isOpen || this.options.topOpen);
3235
+ return this.nodes[0].finish(!!(this.isOpen || this.options.topOpen));
3228
3236
  }
3229
3237
  sync(to) {
3230
- for (let i = this.open; i >= 0; i--)
3238
+ for (let i = this.open; i >= 0; i--) {
3231
3239
  if (this.nodes[i] == to) {
3232
3240
  this.open = i;
3233
3241
  return true;
3234
3242
  }
3243
+ else if (this.localPreserveWS) {
3244
+ this.nodes[i].options |= OPT_PRESERVE_WS;
3245
+ }
3246
+ }
3235
3247
  return false;
3236
3248
  }
3237
3249
  get currentPos() {
@@ -3300,7 +3312,7 @@ class ParseContext {
3300
3312
  let next = depth > 0 || (depth == 0 && useRoot) ? this.nodes[depth].type
3301
3313
  : option && depth >= minDepth ? option.node(depth - minDepth).type
3302
3314
  : null;
3303
- if (!next || (next.name != part && next.groups.indexOf(part) == -1))
3315
+ if (!next || (next.name != part && !next.isInGroup(part)))
3304
3316
  return false;
3305
3317
  depth--;
3306
3318
  }
@@ -3446,6 +3458,8 @@ class DOMSerializer {
3446
3458
  @internal
3447
3459
  */
3448
3460
  serializeNodeInner(node, options) {
3461
+ if (node.isText)
3462
+ return doc$1(options).createTextNode(node.text);
3449
3463
  let { dom, contentDOM } = renderSpec(doc$1(options), this.nodes[node.type.name](node), null, node.attrs);
3450
3464
  if (contentDOM) {
3451
3465
  if (node.isLeaf)
@@ -3480,6 +3494,9 @@ class DOMSerializer {
3480
3494
  return toDOM && renderSpec(doc$1(options), toDOM(mark, inline), null, mark.attrs);
3481
3495
  }
3482
3496
  static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
3497
+ // Kludge for backwards-compatibility with accidental original behavious
3498
+ if (typeof structure == "string")
3499
+ return { dom: doc.createTextNode(structure) };
3483
3500
  return renderSpec(doc, structure, xmlNS, blockArraysIn);
3484
3501
  }
3485
3502
  /**
@@ -3551,11 +3568,9 @@ function suspiciousAttributesInner(attrs) {
3551
3568
  return result;
3552
3569
  }
3553
3570
  function renderSpec(doc, structure, xmlNS, blockArraysIn) {
3554
- if (typeof structure == "string")
3555
- return { dom: doc.createTextNode(structure) };
3556
- if (structure.nodeType != null)
3571
+ if (structure.nodeType == 1)
3557
3572
  return { dom: structure };
3558
- if (structure.dom && structure.dom.nodeType != null)
3573
+ if (structure.dom && structure.dom.nodeType == 1)
3559
3574
  return structure;
3560
3575
  let tagName = structure[0], suspicious;
3561
3576
  if (typeof tagName != "string")
@@ -3578,6 +3593,8 @@ function renderSpec(doc, structure, xmlNS, blockArraysIn) {
3578
3593
  let space = name.indexOf(" ");
3579
3594
  if (space > 0)
3580
3595
  dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
3596
+ else if (name == "style" && dom.style)
3597
+ dom.style.cssText = attrs[name];
3581
3598
  else
3582
3599
  dom.setAttribute(name, attrs[name]);
3583
3600
  }
@@ -3589,6 +3606,9 @@ function renderSpec(doc, structure, xmlNS, blockArraysIn) {
3589
3606
  throw new RangeError("Content hole must be the only child of its parent node");
3590
3607
  return { dom, contentDOM: dom };
3591
3608
  }
3609
+ else if (typeof child == "string") {
3610
+ dom.appendChild(doc.createTextNode(child));
3611
+ }
3592
3612
  else {
3593
3613
  let { dom: inner, contentDOM: innerContent } = renderSpec(doc, child, xmlNS, blockArraysIn);
3594
3614
  dom.appendChild(inner);
@@ -3787,18 +3807,14 @@ A mapping represents a pipeline of zero or more [step
3787
3807
  maps](https://prosemirror.net/docs/ref/#transform.StepMap). It has special provisions for losslessly
3788
3808
  handling mapping positions through a series of steps in which some
3789
3809
  steps are inverted versions of earlier steps. (This comes up when
3790
- ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for
3810
+ ‘[rebasing](https://prosemirror.net/docs/guide/#transform.rebasing)’ steps for
3791
3811
  collaboration or history management.)
3792
3812
  */
3793
3813
  class Mapping {
3794
3814
  /**
3795
3815
  Create a new mapping with the given position maps.
3796
3816
  */
3797
- constructor(
3798
- /**
3799
- The step maps in this mapping.
3800
- */
3801
- maps = [],
3817
+ constructor(maps,
3802
3818
  /**
3803
3819
  @internal
3804
3820
  */
@@ -3811,23 +3827,22 @@ class Mapping {
3811
3827
  /**
3812
3828
  The end position in the `maps` array.
3813
3829
  */
3814
- to = maps.length) {
3815
- this.maps = maps;
3830
+ to = maps ? maps.length : 0) {
3816
3831
  this.mirror = mirror;
3817
3832
  this.from = from;
3818
3833
  this.to = to;
3834
+ this._maps = maps || [];
3835
+ this.ownData = !(maps || mirror);
3819
3836
  }
3820
3837
  /**
3821
- Create a mapping that maps only through a part of this one.
3838
+ The step maps in this mapping.
3822
3839
  */
3823
- slice(from = 0, to = this.maps.length) {
3824
- return new Mapping(this.maps, this.mirror, from, to);
3825
- }
3840
+ get maps() { return this._maps; }
3826
3841
  /**
3827
- @internal
3842
+ Create a mapping that maps only through a part of this one.
3828
3843
  */
3829
- copy() {
3830
- return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to);
3844
+ slice(from = 0, to = this.maps.length) {
3845
+ return new Mapping(this._maps, this.mirror, from, to);
3831
3846
  }
3832
3847
  /**
3833
3848
  Add a step map to the end of this mapping. If `mirrors` is
@@ -3835,18 +3850,23 @@ class Mapping {
3835
3850
  image of this one.
3836
3851
  */
3837
3852
  appendMap(map, mirrors) {
3838
- this.to = this.maps.push(map);
3853
+ if (!this.ownData) {
3854
+ this._maps = this._maps.slice();
3855
+ this.mirror = this.mirror && this.mirror.slice();
3856
+ this.ownData = true;
3857
+ }
3858
+ this.to = this._maps.push(map);
3839
3859
  if (mirrors != null)
3840
- this.setMirror(this.maps.length - 1, mirrors);
3860
+ this.setMirror(this._maps.length - 1, mirrors);
3841
3861
  }
3842
3862
  /**
3843
3863
  Add all the step maps in a given mapping to this one (preserving
3844
3864
  mirroring information).
3845
3865
  */
3846
3866
  appendMapping(mapping) {
3847
- for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) {
3867
+ for (let i = 0, startSize = this._maps.length; i < mapping._maps.length; i++) {
3848
3868
  let mirr = mapping.getMirror(i);
3849
- this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : undefined);
3869
+ this.appendMap(mapping._maps[i], mirr != null && mirr < i ? startSize + mirr : undefined);
3850
3870
  }
3851
3871
  }
3852
3872
  /**
@@ -3872,9 +3892,9 @@ class Mapping {
3872
3892
  Append the inverse of the given mapping to this one.
3873
3893
  */
3874
3894
  appendMappingInverted(mapping) {
3875
- for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) {
3895
+ for (let i = mapping.maps.length - 1, totalSize = this._maps.length + mapping._maps.length; i >= 0; i--) {
3876
3896
  let mirr = mapping.getMirror(i);
3877
- this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : undefined);
3897
+ this.appendMap(mapping._maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : undefined);
3878
3898
  }
3879
3899
  }
3880
3900
  /**
@@ -3892,7 +3912,7 @@ class Mapping {
3892
3912
  if (this.mirror)
3893
3913
  return this._map(pos, assoc, true);
3894
3914
  for (let i = this.from; i < this.to; i++)
3895
- pos = this.maps[i].map(pos, assoc);
3915
+ pos = this._maps[i].map(pos, assoc);
3896
3916
  return pos;
3897
3917
  }
3898
3918
  /**
@@ -3906,12 +3926,12 @@ class Mapping {
3906
3926
  _map(pos, assoc, simple) {
3907
3927
  let delInfo = 0;
3908
3928
  for (let i = this.from; i < this.to; i++) {
3909
- let map = this.maps[i], result = map.mapResult(pos, assoc);
3929
+ let map = this._maps[i], result = map.mapResult(pos, assoc);
3910
3930
  if (result.recover != null) {
3911
3931
  let corr = this.getMirror(i);
3912
3932
  if (corr != null && corr > i && corr < this.to) {
3913
3933
  i = corr;
3914
- pos = this.maps[corr].recover(result.recover);
3934
+ pos = this._maps[corr].recover(result.recover);
3915
3935
  continue;
3916
3936
  }
3917
3937
  }
@@ -4313,10 +4333,11 @@ class ReplaceStep extends Step {
4313
4333
  return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to));
4314
4334
  }
4315
4335
  map(mapping) {
4316
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
4336
+ let to = mapping.mapResult(this.to, -1);
4337
+ let from = this.from == this.to && ReplaceStep.MAP_BIAS < 0 ? to : mapping.mapResult(this.from, 1);
4317
4338
  if (from.deletedAcross && to.deletedAcross)
4318
4339
  return null;
4319
- return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice);
4340
+ return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
4320
4341
  }
4321
4342
  merge(other) {
4322
4343
  if (!(other instanceof ReplaceStep) || other.structure || this.structure)
@@ -4352,6 +4373,15 @@ class ReplaceStep extends Step {
4352
4373
  return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure);
4353
4374
  }
4354
4375
  }
4376
+ /**
4377
+ By default, for backwards compatibility, an inserting step
4378
+ mapped over an insertion at that same position fill move after
4379
+ the inserted content. In a collaborative editing situation, that
4380
+ can make redone insertions appear in unexpected places. You can
4381
+ set this to -1 to make such mapping keep the step before the
4382
+ insertion instead.
4383
+ */
4384
+ ReplaceStep.MAP_BIAS = 1;
4355
4385
  Step.jsonID("replace", ReplaceStep);
4356
4386
  /**
4357
4387
  Replace a part of the document with a slice of content, but
@@ -4584,13 +4614,17 @@ can be lifted. Will not go across
4584
4614
  function liftTarget(range) {
4585
4615
  let parent = range.parent;
4586
4616
  let content = parent.content.cutByIndex(range.startIndex, range.endIndex);
4587
- for (let depth = range.depth;; --depth) {
4617
+ for (let depth = range.depth, contentBefore = 0, contentAfter = 0;; --depth) {
4588
4618
  let node = range.$from.node(depth);
4589
- let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth);
4619
+ let index = range.$from.index(depth) + contentBefore, endIndex = range.$to.indexAfter(depth) - contentAfter;
4590
4620
  if (depth < range.depth && node.canReplace(index, endIndex, content))
4591
4621
  return depth;
4592
4622
  if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex))
4593
4623
  break;
4624
+ if (index)
4625
+ contentBefore = 1;
4626
+ if (endIndex < node.childCount)
4627
+ contentAfter = 1;
4594
4628
  }
4595
4629
  return null;
4596
4630
  }
@@ -5241,7 +5275,7 @@ function replaceRange(tr, from, to, slice) {
5241
5275
  let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
5242
5276
  if (fitsTrivially($from, $to, slice))
5243
5277
  return tr.step(new ReplaceStep(from, to, slice));
5244
- let targetDepths = coveredDepths($from, tr.doc.resolve(to));
5278
+ let targetDepths = coveredDepths($from, $to);
5245
5279
  // Can't replace the whole document, so remove 0 if it's present
5246
5280
  if (targetDepths[targetDepths.length - 1] == 0)
5247
5281
  targetDepths.pop();
@@ -5334,6 +5368,26 @@ function replaceRangeWith(tr, from, to, node) {
5334
5368
  }
5335
5369
  function deleteRange(tr, from, to) {
5336
5370
  let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
5371
+ // When the deleted range spans from the start of one textblock to
5372
+ // the start of another one, move out of the start of both blocks.
5373
+ if ($from.parent.isTextblock && $to.parent.isTextblock && $from.start() != $to.start() &&
5374
+ $from.parentOffset == 0 && $to.parentOffset == 0) {
5375
+ let shared = $from.sharedDepth(to), isolated = false;
5376
+ for (let d = $from.depth; d > shared; d--)
5377
+ if ($from.node(d).type.spec.isolating)
5378
+ isolated = true;
5379
+ for (let d = $to.depth; d > shared; d--)
5380
+ if ($to.node(d).type.spec.isolating)
5381
+ isolated = true;
5382
+ if (!isolated) {
5383
+ for (let d = $from.depth; d > 0 && from == $from.start(d); d--)
5384
+ from = $from.before(d);
5385
+ for (let d = $to.depth; d > 0 && to == $to.start(d); d--)
5386
+ to = $to.before(d);
5387
+ $from = tr.doc.resolve(from);
5388
+ $to = tr.doc.resolve(to);
5389
+ }
5390
+ }
5337
5391
  let covered = coveredDepths($from, $to);
5338
5392
  for (let i = 0; i < covered.length; i++) {
5339
5393
  let depth = covered[i], last = i == covered.length - 1;
@@ -5544,6 +5598,27 @@ class Transform {
5544
5598
  return this.steps.length > 0;
5545
5599
  }
5546
5600
  /**
5601
+ Return a single range, in post-transform document positions,
5602
+ that covers all content changed by this transform. Returns null
5603
+ if no replacements are made. Note that this will ignore changes
5604
+ that add/remove marks without replacing the underlying content.
5605
+ */
5606
+ changedRange() {
5607
+ let from = 1e9, to = -1e9;
5608
+ for (let i = 0; i < this.mapping.maps.length; i++) {
5609
+ let map = this.mapping.maps[i];
5610
+ if (i) {
5611
+ from = map.map(from, 1);
5612
+ to = map.map(to, -1);
5613
+ }
5614
+ map.forEach((_f, _t, fromB, toB) => {
5615
+ from = Math.min(from, fromB);
5616
+ to = Math.max(to, toB);
5617
+ });
5618
+ }
5619
+ return from == 1e9 ? null : { from, to };
5620
+ }
5621
+ /**
5547
5622
  @internal
5548
5623
  */
5549
5624
  addStep(step, doc) {
@@ -5693,19 +5768,26 @@ class Transform {
5693
5768
  return this;
5694
5769
  }
5695
5770
  /**
5696
- Remove a mark (or a mark of the given type) from the node at
5771
+ Remove a mark (or all marks of the given type) from the node at
5697
5772
  position `pos`.
5698
5773
  */
5699
5774
  removeNodeMark(pos, mark) {
5700
- if (!(mark instanceof Mark)) {
5701
- let node = this.doc.nodeAt(pos);
5702
- if (!node)
5703
- throw new RangeError("No node at position " + pos);
5704
- mark = mark.isInSet(node.marks);
5705
- if (!mark)
5706
- return this;
5775
+ let node = this.doc.nodeAt(pos);
5776
+ if (!node)
5777
+ throw new RangeError("No node at position " + pos);
5778
+ if (mark instanceof Mark) {
5779
+ if (mark.isInSet(node.marks))
5780
+ this.step(new RemoveNodeMarkStep(pos, mark));
5781
+ }
5782
+ else {
5783
+ let set = node.marks, found, steps = [];
5784
+ while (found = mark.isInSet(set)) {
5785
+ steps.push(new RemoveNodeMarkStep(pos, found));
5786
+ set = found.removeFromSet(set);
5787
+ }
5788
+ for (let i = steps.length - 1; i >= 0; i--)
5789
+ this.step(steps[i]);
5707
5790
  }
5708
- this.step(new RemoveNodeMarkStep(pos, mark));
5709
5791
  return this;
5710
5792
  }
5711
5793
  /**
@@ -5713,7 +5795,7 @@ class Transform {
5713
5795
  greater than one, any number of nodes above that. By default, the
5714
5796
  parts split off will inherit the node type of the original node.
5715
5797
  This can be changed by passing an array of types and attributes to
5716
- use after the split.
5798
+ use after the split (with the outermost nodes coming first).
5717
5799
  */
5718
5800
  split(pos, depth = 1, typesAfter) {
5719
5801
  split(this, pos, depth, typesAfter);
@@ -6381,7 +6463,6 @@ class Transaction extends Transform {
6381
6463
  else {
6382
6464
  if (to == null)
6383
6465
  to = from;
6384
- to = to == null ? from : to;
6385
6466
  if (!text)
6386
6467
  return this.deleteRange(from, to);
6387
6468
  let marks = this.storedMarks;
@@ -6390,7 +6471,7 @@ class Transaction extends Transform {
6390
6471
  marks = to == from ? $from.marks() : $from.marksAcross(this.doc.resolve(to));
6391
6472
  }
6392
6473
  this.replaceRangeWith(from, to, schema.text(text, marks));
6393
- if (!this.selection.empty)
6474
+ if (!this.selection.empty && this.selection.to == from + text.length)
6394
6475
  this.setSelection(Selection.near(this.selection.$to));
6395
6476
  return this;
6396
6477
  }
@@ -6586,7 +6667,7 @@ class EditorState {
6586
6667
  return newInstance;
6587
6668
  }
6588
6669
  /**
6589
- Start a [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state.
6670
+ Accessor that constructs and returns a new [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state.
6590
6671
  */
6591
6672
  get tr() { return new Transaction(this); }
6592
6673
  /**
@@ -6780,6 +6861,7 @@ const isEquivalentPosition = function (node, off, targetNode, targetOff) {
6780
6861
  };
6781
6862
  const atomElements = /^(img|br|input|textarea|hr)$/i;
6782
6863
  function scanFor(node, off, targetNode, targetOff, dir) {
6864
+ var _a;
6783
6865
  for (;;) {
6784
6866
  if (node == targetNode && off == targetOff)
6785
6867
  return true;
@@ -6792,10 +6874,17 @@ function scanFor(node, off, targetNode, targetOff, dir) {
6792
6874
  node = parent;
6793
6875
  }
6794
6876
  else if (node.nodeType == 1) {
6795
- node = node.childNodes[off + (dir < 0 ? -1 : 0)];
6796
- if (node.contentEditable == "false")
6797
- return false;
6798
- off = dir < 0 ? nodeSize(node) : 0;
6877
+ let child = node.childNodes[off + (dir < 0 ? -1 : 0)];
6878
+ if (child.nodeType == 1 && child.contentEditable == "false") {
6879
+ if ((_a = child.pmViewDesc) === null || _a === void 0 ? void 0 : _a.ignoreForSelection)
6880
+ off += dir;
6881
+ else
6882
+ return false;
6883
+ }
6884
+ else {
6885
+ node = child;
6886
+ off = dir < 0 ? nodeSize(node) : 0;
6887
+ }
6799
6888
  }
6800
6889
  else {
6801
6890
  return false;
@@ -6915,7 +7004,7 @@ const safari = !ie$1 && !!nav && /Apple Computer/.test(nav.vendor);
6915
7004
  // Is true for both iOS and iPadOS for convenience
6916
7005
  const ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2);
6917
7006
  const mac$4 = ios || (nav ? /Mac/.test(nav.platform) : false);
6918
- const windows = nav ? /Win/.test(nav.platform) : false;
7007
+ const windows$1 = nav ? /Win/.test(nav.platform) : false;
6919
7008
  const android = /Android \d/.test(agent);
6920
7009
  const webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style;
6921
7010
  const webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0;
@@ -6945,11 +7034,13 @@ function clientRect(node) {
6945
7034
  function scrollRectIntoView(view, rect, startDOM) {
6946
7035
  let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5;
6947
7036
  let doc = view.dom.ownerDocument;
6948
- for (let parent = startDOM || view.dom;; parent = parentNode(parent)) {
7037
+ for (let parent = startDOM || view.dom;;) {
6949
7038
  if (!parent)
6950
7039
  break;
6951
- if (parent.nodeType != 1)
7040
+ if (parent.nodeType != 1) {
7041
+ parent = parentNode(parent);
6952
7042
  continue;
7043
+ }
6953
7044
  let elt = parent;
6954
7045
  let atTop = elt == doc.body;
6955
7046
  let bounding = atTop ? windowRect(doc) : clientRect(elt);
@@ -6978,8 +7069,10 @@ function scrollRectIntoView(view, rect, startDOM) {
6978
7069
  rect = { left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY };
6979
7070
  }
6980
7071
  }
6981
- if (atTop || /^(fixed|sticky)$/.test(getComputedStyle(parent).position))
7072
+ let pos = atTop ? "fixed" : getComputedStyle(parent).position;
7073
+ if (/^(fixed|sticky)$/.test(pos))
6982
7074
  break;
7075
+ parent = pos == "absolute" ? parent.offsetParent : parentNode(parent);
6983
7076
  }
6984
7077
  }
6985
7078
  // Store the scroll position of the editor's parent nodes, along with
@@ -7099,17 +7192,20 @@ function findOffsetInNode(node, coords) {
7099
7192
  }
7100
7193
  function findOffsetInText(node, coords) {
7101
7194
  let len = node.nodeValue.length;
7102
- let range = document.createRange();
7195
+ let range = document.createRange(), result;
7103
7196
  for (let i = 0; i < len; i++) {
7104
7197
  range.setEnd(node, i + 1);
7105
7198
  range.setStart(node, i);
7106
7199
  let rect = singleRect(range, 1);
7107
7200
  if (rect.top == rect.bottom)
7108
7201
  continue;
7109
- if (inRect(coords, rect))
7110
- return { node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) };
7202
+ if (inRect(coords, rect)) {
7203
+ result = { node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) };
7204
+ break;
7205
+ }
7111
7206
  }
7112
- return { node, offset: 0 };
7207
+ range.detach();
7208
+ return result || { node, offset: 0 };
7113
7209
  }
7114
7210
  function inRect(coords, rect) {
7115
7211
  return coords.left >= rect.left - 1 && coords.left <= rect.right + 1 &&
@@ -7146,7 +7242,7 @@ function posFromCaret(view, node, offset, coords) {
7146
7242
  if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) &&
7147
7243
  // Ignore elements with zero-size bounding rectangles
7148
7244
  ((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
7149
- if (desc.node.isBlock && desc.parent) {
7245
+ if (desc.node.isBlock && desc.parent && !/^T(R|BODY|HEAD|FOOT)$/.test(desc.dom.nodeName)) {
7150
7246
  // Only apply the horizontal test to the innermost block. Vertical for any parent.
7151
7247
  if (!sawBlock && rect.left > coords.left || rect.top > coords.top)
7152
7248
  outsideBlock = desc.posBefore;
@@ -7804,7 +7900,7 @@ class ViewDesc {
7804
7900
  // (one where the focus is before the anchor), but not all
7805
7901
  // browsers support it yet.
7806
7902
  let domSelExtended = false;
7807
- if ((domSel.extend || anchor == head) && !brKludge) {
7903
+ if ((domSel.extend || anchor == head) && !(brKludge && gecko)) {
7808
7904
  domSel.collapse(anchorDOM.node, anchorDOM.offset);
7809
7905
  try {
7810
7906
  if (anchor != head)
@@ -7874,6 +7970,7 @@ class ViewDesc {
7874
7970
  }
7875
7971
  get domAtom() { return false; }
7876
7972
  get ignoreForCoords() { return false; }
7973
+ get ignoreForSelection() { return false; }
7877
7974
  isText(text) { return false; }
7878
7975
  }
7879
7976
  // A widget desc represents a widget decoration, which is a DOM node
@@ -7918,6 +8015,7 @@ class WidgetViewDesc extends ViewDesc {
7918
8015
  super.destroy();
7919
8016
  }
7920
8017
  get domAtom() { return true; }
8018
+ get ignoreForSelection() { return !!this.widget.type.spec.relaxedSide; }
7921
8019
  get side() { return this.widget.type.side; }
7922
8020
  }
7923
8021
  class CompositionViewDesc extends ViewDesc {
@@ -8103,15 +8201,15 @@ class NodeViewDesc extends ViewDesc {
8103
8201
  let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
8104
8202
  iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => {
8105
8203
  if (widget.spec.marks)
8106
- updater.syncToMarks(widget.spec.marks, inline, view);
8204
+ updater.syncToMarks(widget.spec.marks, inline, view, i);
8107
8205
  else if (widget.type.side >= 0 && !insideNode)
8108
- updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.child(i).marks, inline, view);
8206
+ updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.child(i).marks, inline, view, i);
8109
8207
  // If the next node is a desc matching this widget, reuse it,
8110
8208
  // otherwise insert the widget as a new view desc.
8111
8209
  updater.placeWidget(widget, view, off);
8112
8210
  }, (child, outerDeco, innerDeco, i) => {
8113
8211
  // Make sure the wrapping mark descs match the node's marks.
8114
- updater.syncToMarks(child.marks, inline, view);
8212
+ updater.syncToMarks(child.marks, inline, view, i);
8115
8213
  // Try several strategies for drawing this node
8116
8214
  let compIndex;
8117
8215
  if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) ;
@@ -8127,7 +8225,7 @@ class NodeViewDesc extends ViewDesc {
8127
8225
  off += child.nodeSize;
8128
8226
  });
8129
8227
  // Drop all remaining descs after the current position.
8130
- updater.syncToMarks([], inline, view);
8228
+ updater.syncToMarks([], inline, view, 0);
8131
8229
  if (this.node.isTextblock)
8132
8230
  updater.addTextblockHacks();
8133
8231
  updater.destroyRest();
@@ -8214,17 +8312,18 @@ class NodeViewDesc extends ViewDesc {
8214
8312
  }
8215
8313
  // Mark this node as being the selected node.
8216
8314
  selectNode() {
8217
- if (this.nodeDOM.nodeType == 1)
8315
+ if (this.nodeDOM.nodeType == 1) {
8218
8316
  this.nodeDOM.classList.add("ProseMirror-selectednode");
8219
- if (this.contentDOM || !this.node.type.spec.draggable)
8220
- this.dom.draggable = true;
8317
+ if (this.contentDOM || !this.node.type.spec.draggable)
8318
+ this.nodeDOM.draggable = true;
8319
+ }
8221
8320
  }
8222
8321
  // Remove selected node marking from this node.
8223
8322
  deselectNode() {
8224
8323
  if (this.nodeDOM.nodeType == 1) {
8225
8324
  this.nodeDOM.classList.remove("ProseMirror-selectednode");
8226
8325
  if (this.contentDOM || !this.node.type.spec.draggable)
8227
- this.dom.removeAttribute("draggable");
8326
+ this.nodeDOM.removeAttribute("draggable");
8228
8327
  }
8229
8328
  }
8230
8329
  get domAtom() { return this.node.isAtom; }
@@ -8516,7 +8615,7 @@ class ViewTreeUpdater {
8516
8615
  }
8517
8616
  // Sync the current stack of mark descs with the given array of
8518
8617
  // marks, reusing existing mark descs when possible.
8519
- syncToMarks(marks, inline, view) {
8618
+ syncToMarks(marks, inline, view, parentIndex) {
8520
8619
  let keep = 0, depth = this.stack.length >> 1;
8521
8620
  let maxKeep = Math.min(depth, marks.length);
8522
8621
  while (keep < maxKeep &&
@@ -8532,8 +8631,10 @@ class ViewTreeUpdater {
8532
8631
  }
8533
8632
  while (depth < marks.length) {
8534
8633
  this.stack.push(this.top, this.index + 1);
8535
- let found = -1;
8536
- for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) {
8634
+ let found = -1, scanTo = this.top.children.length;
8635
+ if (parentIndex < this.preMatch.index)
8636
+ scanTo = Math.min(this.index + 3, scanTo);
8637
+ for (let i = this.index; i < scanTo; i++) {
8537
8638
  let next = this.top.children[i];
8538
8639
  if (next.matchesMark(marks[depth]) && !this.isLocked(next.dom)) {
8539
8640
  found = i;
@@ -8729,9 +8830,7 @@ class ViewTreeUpdater {
8729
8830
  }
8730
8831
  // Iterate from the end of the fragment and array of descs to find
8731
8832
  // directly matching ones, in order to avoid overeagerly reusing those
8732
- // for other nodes. Returns the fragment index of the first node that
8733
- // is part of the sequence of matched nodes at the end of the
8734
- // fragment.
8833
+ // for other nodes.
8735
8834
  function preMatch(frag, parentDesc) {
8736
8835
  let curDesc = parentDesc, descI = curDesc.children.length;
8737
8836
  let fI = frag.childCount, matched = new Map, matches = [];
@@ -8754,7 +8853,6 @@ function preMatch(frag, parentDesc) {
8754
8853
  break outer;
8755
8854
  }
8756
8855
  else {
8757
- // FIXME
8758
8856
  descI = curDesc.parent.children.indexOf(curDesc);
8759
8857
  curDesc = curDesc.parent;
8760
8858
  }
@@ -9063,17 +9161,14 @@ function removeClassOnSelectionChange(view) {
9063
9161
  });
9064
9162
  }
9065
9163
  function selectCursorWrapper(view) {
9066
- let domSel = view.domSelection(), range = document.createRange();
9164
+ let domSel = view.domSelection();
9067
9165
  if (!domSel)
9068
9166
  return;
9069
9167
  let node = view.cursorWrapper.dom, img = node.nodeName == "IMG";
9070
9168
  if (img)
9071
- range.setStart(node.parentNode, domIndex(node) + 1);
9169
+ domSel.collapse(node.parentNode, domIndex(node) + 1);
9072
9170
  else
9073
- range.setStart(node, 0);
9074
- range.collapse(true);
9075
- domSel.removeAllRanges();
9076
- domSel.addRange(range);
9171
+ domSel.collapse(node, 0);
9077
9172
  // Kludge to kill 'control selection' in IE11 when selecting an
9078
9173
  // invisible cursor wrapper, since that would result in those weird
9079
9174
  // resize handles and a selection that considers the absolutely
@@ -9381,7 +9476,7 @@ function setSelFocus(view, node, offset) {
9381
9476
  }
9382
9477
  function findDirection(view, pos) {
9383
9478
  let $pos = view.state.doc.resolve(pos);
9384
- if (!(chrome || windows) && $pos.parent.inlineContent) {
9479
+ if (!(chrome || windows$1) && $pos.parent.inlineContent) {
9385
9480
  let coords = view.coordsAtPos(pos);
9386
9481
  if (pos > $pos.start()) {
9387
9482
  let before = view.coordsAtPos(pos - 1);
@@ -9551,11 +9646,14 @@ function parseFromClipboard(view, text, html, plainText, $context) {
9551
9646
  let dom, slice;
9552
9647
  if (!html && !text)
9553
9648
  return null;
9554
- let asText = text && (plainText || inCode || !html);
9649
+ let asText = !!text && (plainText || inCode || !html);
9555
9650
  if (asText) {
9556
9651
  view.someProp("transformPastedText", f => { text = f(text, inCode || plainText, view); });
9557
- if (inCode)
9558
- return text ? new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0) : Slice.empty;
9652
+ if (inCode) {
9653
+ slice = new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0);
9654
+ view.someProp("transformPasted", f => { slice = f(slice, view, true); });
9655
+ return slice;
9656
+ }
9559
9657
  let parsed = view.someProp("clipboardTextParser", f => f(text, $context, plainText, view));
9560
9658
  if (parsed) {
9561
9659
  slice = parsed;
@@ -9613,7 +9711,7 @@ function parseFromClipboard(view, text, html, plainText, $context) {
9613
9711
  slice = closeSlice(slice, openStart, openEnd);
9614
9712
  }
9615
9713
  }
9616
- view.someProp("transformPasted", f => { slice = f(slice, view); });
9714
+ view.someProp("transformPasted", f => { slice = f(slice, view, asText); });
9617
9715
  return slice;
9618
9716
  }
9619
9717
  const inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;
@@ -9724,7 +9822,7 @@ function maybeWrapTrusted(html) {
9724
9822
  // innerHTML, even on a detached document. This wraps the string in
9725
9823
  // a way that makes the browser allow us to use its parser again.
9726
9824
  if (!_policy)
9727
- _policy = trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
9825
+ _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
9728
9826
  return _policy.createHTML(html);
9729
9827
  }
9730
9828
  function readHTML(html) {
@@ -9787,7 +9885,7 @@ class InputState {
9787
9885
  this.mouseDown = null;
9788
9886
  this.lastKeyCode = null;
9789
9887
  this.lastKeyCodeTime = 0;
9790
- this.lastClick = { time: 0, x: 0, y: 0, type: "" };
9888
+ this.lastClick = { time: 0, x: 0, y: 0, type: "", button: 0 };
9791
9889
  this.lastSelectionOrigin = null;
9792
9890
  this.lastSelectionTime = 0;
9793
9891
  this.lastIOSEnter = 0;
@@ -9801,6 +9899,7 @@ class InputState {
9801
9899
  this.compositionNodes = [];
9802
9900
  this.compositionEndedAt = -2e8;
9803
9901
  this.compositionID = 1;
9902
+ this.badSafariComposition = false;
9804
9903
  // Set to a composition ID when there are pending changes at compositionend
9805
9904
  this.compositionPendingChanges = 0;
9806
9905
  this.domChangeCount = 0;
@@ -9915,8 +10014,9 @@ editHandlers.keypress = (view, _event) => {
9915
10014
  let sel = view.state.selection;
9916
10015
  if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) {
9917
10016
  let text = String.fromCharCode(event.charCode);
9918
- if (!/[\r\n]/.test(text) && !view.someProp("handleTextInput", f => f(view, sel.$from.pos, sel.$to.pos, text)))
9919
- view.dispatch(view.state.tr.insertText(text).scrollIntoView());
10017
+ let deflt = () => view.state.tr.insertText(text).scrollIntoView();
10018
+ if (!/[\r\n]/.test(text) && !view.someProp("handleTextInput", f => f(view, sel.$from.pos, sel.$to.pos, text, deflt)))
10019
+ view.dispatch(deflt());
9920
10020
  event.preventDefault();
9921
10021
  }
9922
10022
  };
@@ -10028,13 +10128,14 @@ handlers.mousedown = (view, _event) => {
10028
10128
  view.input.shiftKey = event.shiftKey;
10029
10129
  let flushed = forceDOMFlush(view);
10030
10130
  let now = Date.now(), type = "singleClick";
10031
- if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier]) {
10131
+ if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier] &&
10132
+ view.input.lastClick.button == event.button) {
10032
10133
  if (view.input.lastClick.type == "singleClick")
10033
10134
  type = "doubleClick";
10034
10135
  else if (view.input.lastClick.type == "doubleClick")
10035
10136
  type = "tripleClick";
10036
10137
  }
10037
- view.input.lastClick = { time: now, x: event.clientX, y: event.clientY, type };
10138
+ view.input.lastClick = { time: now, x: event.clientX, y: event.clientY, type, button: event.button };
10038
10139
  let pos = view.posAtCoords(eventCoords(event));
10039
10140
  if (!pos)
10040
10141
  return;
@@ -10073,11 +10174,11 @@ class MouseDown {
10073
10174
  }
10074
10175
  const target = flushed ? null : event.target;
10075
10176
  const targetDesc = target ? view.docView.nearestDesc(target, true) : null;
10076
- this.target = targetDesc && targetDesc.dom.nodeType == 1 ? targetDesc.dom : null;
10177
+ this.target = targetDesc && targetDesc.nodeDOM.nodeType == 1 ? targetDesc.nodeDOM : null;
10077
10178
  let { selection } = view.state;
10078
10179
  if (event.button == 0 &&
10079
- targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
10080
- selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos)
10180
+ (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
10181
+ selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos))
10081
10182
  this.mightDrag = {
10082
10183
  node: targetNode,
10083
10184
  pos: targetPos,
@@ -10197,7 +10298,8 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
10197
10298
  let { state } = view, $pos = state.selection.$to;
10198
10299
  if (state.selection instanceof TextSelection &&
10199
10300
  (state.storedMarks ||
10200
- (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) {
10301
+ (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)) ||
10302
+ chrome && windows$1 && selectionBeforeUneditable(view))) { // Issue #1500
10201
10303
  // Need to wrap the cursor in mark nodes different from the ones in the DOM context
10202
10304
  view.markCursor = view.state.storedMarks || $pos.marks();
10203
10305
  endComposition(view, true);
@@ -10231,13 +10333,22 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
10231
10333
  }
10232
10334
  scheduleComposeEnd(view, timeoutComposition);
10233
10335
  };
10336
+ function selectionBeforeUneditable(view) {
10337
+ let { focusNode, focusOffset } = view.domSelectionRange();
10338
+ if (!focusNode || focusNode.nodeType != 1 || focusOffset >= focusNode.childNodes.length)
10339
+ return false;
10340
+ let next = focusNode.childNodes[focusOffset];
10341
+ return next.nodeType == 1 && next.contentEditable == "false";
10342
+ }
10234
10343
  editHandlers.compositionend = (view, event) => {
10235
10344
  if (view.composing) {
10236
10345
  view.input.composing = false;
10237
10346
  view.input.compositionEndedAt = event.timeStamp;
10238
10347
  view.input.compositionPendingChanges = view.domObserver.pendingRecords().length ? view.input.compositionID : 0;
10239
10348
  view.input.compositionNode = null;
10240
- if (view.input.compositionPendingChanges)
10349
+ if (view.input.badSafariComposition)
10350
+ view.domObserver.forceFlush();
10351
+ else if (view.input.compositionPendingChanges)
10241
10352
  Promise.resolve().then(() => view.domObserver.flush());
10242
10353
  view.input.compositionID++;
10243
10354
  scheduleComposeEnd(view, 20);
@@ -10291,10 +10402,10 @@ function endComposition(view, restarting = false) {
10291
10402
  view.domObserver.forceFlush();
10292
10403
  clearComposition(view);
10293
10404
  if (restarting || view.docView && view.docView.dirty) {
10294
- let sel = selectionFromDOM(view);
10295
- if (sel && !sel.eq(view.state.selection))
10405
+ let sel = selectionFromDOM(view), cur = view.state.selection;
10406
+ if (sel && !sel.eq(cur))
10296
10407
  view.dispatch(view.state.tr.setSelection(sel));
10297
- else if ((view.markCursor || restarting) && !view.state.selection.empty)
10408
+ else if ((view.markCursor || restarting) && !cur.$from.node(cur.$from.sharedDepth(cur.to)).inlineContent)
10298
10409
  view.dispatch(view.state.tr.deleteSelection());
10299
10410
  else
10300
10411
  view.updateState(view.state);
@@ -10415,6 +10526,11 @@ class Dragging {
10415
10526
  }
10416
10527
  }
10417
10528
  const dragCopyModifier = mac$4 ? "altKey" : "ctrlKey";
10529
+ function dragMoves(view, event) {
10530
+ let copy;
10531
+ view.someProp("dragCopies", test => { copy = copy || test(event); });
10532
+ return copy != null ? !copy : !event[dragCopyModifier];
10533
+ }
10418
10534
  handlers.dragstart = (view, _event) => {
10419
10535
  let event = _event;
10420
10536
  let mouseDown = view.input.mouseDown;
@@ -10440,11 +10556,11 @@ handlers.dragstart = (view, _event) => {
10440
10556
  if (!event.dataTransfer.files.length || !chrome || chrome_version > 120)
10441
10557
  event.dataTransfer.clearData();
10442
10558
  event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML);
10443
- // See https://github.com/ProseMirror/prosemirror/issues/1156
10559
+ // See https://code.haverbeke.berlin/prosemirror/prosemirror/issues/1156
10444
10560
  event.dataTransfer.effectAllowed = "copyMove";
10445
10561
  if (!brokenClipboardAPI)
10446
10562
  event.dataTransfer.setData("text/plain", text);
10447
- view.dragging = new Dragging(slice, !event[dragCopyModifier], node);
10563
+ view.dragging = new Dragging(slice, dragMoves(view, event), node);
10448
10564
  };
10449
10565
  handlers.dragend = view => {
10450
10566
  let dragging = view.dragging;
@@ -10454,10 +10570,15 @@ handlers.dragend = view => {
10454
10570
  }, 50);
10455
10571
  };
10456
10572
  editHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault();
10457
- editHandlers.drop = (view, _event) => {
10458
- let event = _event;
10459
- let dragging = view.dragging;
10460
- view.dragging = null;
10573
+ editHandlers.drop = (view, event) => {
10574
+ try {
10575
+ handleDrop(view, event, view.dragging);
10576
+ }
10577
+ finally {
10578
+ view.dragging = null;
10579
+ }
10580
+ };
10581
+ function handleDrop(view, event, dragging) {
10461
10582
  if (!event.dataTransfer)
10462
10583
  return;
10463
10584
  let eventPos = view.posAtCoords(eventCoords(event));
@@ -10466,12 +10587,12 @@ editHandlers.drop = (view, _event) => {
10466
10587
  let $mouse = view.state.doc.resolve(eventPos.pos);
10467
10588
  let slice = dragging && dragging.slice;
10468
10589
  if (slice) {
10469
- view.someProp("transformPasted", f => { slice = f(slice, view); });
10590
+ view.someProp("transformPasted", f => { slice = f(slice, view, false); });
10470
10591
  }
10471
10592
  else {
10472
10593
  slice = parseFromClipboard(view, getText(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
10473
10594
  }
10474
- let move = !!(dragging && !event[dragCopyModifier]);
10595
+ let move = !!(dragging && dragMoves(view, event));
10475
10596
  if (view.someProp("handleDrop", f => f(view, event, slice || Slice.empty, move))) {
10476
10597
  event.preventDefault();
10477
10598
  return;
@@ -10511,7 +10632,7 @@ editHandlers.drop = (view, _event) => {
10511
10632
  }
10512
10633
  view.focus();
10513
10634
  view.dispatch(tr.setMeta("uiEvent", "drop"));
10514
- };
10635
+ }
10515
10636
  handlers.focus = view => {
10516
10637
  view.input.lastFocus = Date.now();
10517
10638
  if (!view.focused) {
@@ -11291,15 +11412,24 @@ class DOMObserver {
11291
11412
  new window.MutationObserver(mutations => {
11292
11413
  for (let i = 0; i < mutations.length; i++)
11293
11414
  this.queue.push(mutations[i]);
11294
- // IE11 will sometimes (on backspacing out a single character
11295
- // text node after a BR node) call the observer callback
11296
- // before actually updating the DOM, which will cause
11297
- // ProseMirror to miss the change (see #930)
11298
11415
  if (ie$1 && ie_version <= 11 && mutations.some(m => m.type == "childList" && m.removedNodes.length ||
11299
- m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length))
11416
+ m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length)) {
11417
+ // IE11 will sometimes (on backspacing out a single character
11418
+ // text node after a BR node) call the observer callback
11419
+ // before actually updating the DOM, which will cause
11420
+ // ProseMirror to miss the change (see #930)
11300
11421
  this.flushSoon();
11301
- else
11422
+ }
11423
+ else if (safari && view.composing && mutations.some(m => m.type == "childList" && m.target.nodeName == "TR")) {
11424
+ // Safari does weird stuff when finishing a composition in a
11425
+ // table cell, which tends to involve inserting inappropriate
11426
+ // nodes in the table row.
11427
+ view.input.badSafariComposition = true;
11428
+ this.flushSoon();
11429
+ }
11430
+ else {
11302
11431
  this.flush();
11432
+ }
11303
11433
  });
11304
11434
  if (useCharData) {
11305
11435
  this.onCharData = e => {
@@ -11419,7 +11549,22 @@ class DOMObserver {
11419
11549
  }
11420
11550
  }
11421
11551
  }
11422
- if (gecko && added.length) {
11552
+ if (added.some(n => n.nodeName == "BR") && (view.input.lastKeyCode == 8 || view.input.lastKeyCode == 46)) {
11553
+ // Browsers sometimes insert a bogus break node if you
11554
+ // backspace out the last bit of text before an inline-flex node (#1552)
11555
+ for (let node of added)
11556
+ if (node.nodeName == "BR" && node.parentNode) {
11557
+ let after = node.nextSibling;
11558
+ while (after && after.nodeType == 1) {
11559
+ if (after.contentEditable == "false") {
11560
+ node.parentNode.removeChild(node);
11561
+ break;
11562
+ }
11563
+ after = after.firstChild;
11564
+ }
11565
+ }
11566
+ }
11567
+ else if (gecko && added.length) {
11423
11568
  let brs = added.filter(n => n.nodeName == "BR");
11424
11569
  if (brs.length == 2) {
11425
11570
  let [a, b] = brs;
@@ -11455,6 +11600,10 @@ class DOMObserver {
11455
11600
  view.docView.markDirty(from, to);
11456
11601
  checkCSS(view);
11457
11602
  }
11603
+ if (view.input.badSafariComposition) {
11604
+ view.input.badSafariComposition = false;
11605
+ fixUpBadSafariComposition(view, added);
11606
+ }
11458
11607
  this.handleDOMChange(from, to, typeOver, added);
11459
11608
  if (view.docView && view.docView.dirty)
11460
11609
  view.updateState(view.state);
@@ -11578,6 +11727,37 @@ function blockParent(view, node) {
11578
11727
  }
11579
11728
  return null;
11580
11729
  }
11730
+ // Kludge for a Safari bug where, on ending a composition in an
11731
+ // otherwise empty table cell, it randomly moves the composed text
11732
+ // into the table row around that cell, greatly confusing everything
11733
+ // (#188).
11734
+ function fixUpBadSafariComposition(view, addedNodes) {
11735
+ var _a;
11736
+ let { focusNode, focusOffset } = view.domSelectionRange();
11737
+ for (let node of addedNodes) {
11738
+ if (((_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.nodeName) == "TR") {
11739
+ let nextCell = node.nextSibling;
11740
+ while (nextCell && (nextCell.nodeName != "TD" && nextCell.nodeName != "TH"))
11741
+ nextCell = nextCell.nextSibling;
11742
+ if (nextCell) {
11743
+ let parent = nextCell;
11744
+ for (;;) {
11745
+ let first = parent.firstChild;
11746
+ if (!first || first.nodeType != 1 || first.contentEditable == "false" ||
11747
+ /^(BR|IMG)$/.test(first.nodeName))
11748
+ break;
11749
+ parent = first;
11750
+ }
11751
+ parent.insertBefore(node, parent.firstChild);
11752
+ if (focusNode == node)
11753
+ view.domSelection().collapse(node, focusOffset);
11754
+ }
11755
+ else {
11756
+ node.parentNode.removeChild(node);
11757
+ }
11758
+ }
11759
+ }
11760
+ }
11581
11761
 
11582
11762
  // Note that all referencing and parsing is done with the
11583
11763
  // start-of-operation selection and document, since that's the one
@@ -11652,7 +11832,7 @@ function ruleFromNode(dom) {
11652
11832
  }
11653
11833
  return null;
11654
11834
  }
11655
- const isInline = /^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i;
11835
+ const isInline = /^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|img|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i;
11656
11836
  function readDOMChange(view, from, to, typeOver, addedNodes) {
11657
11837
  let compositionID = view.input.compositionPendingChanges || (view.composing ? view.input.compositionID : 0);
11658
11838
  view.input.compositionPendingChanges = 0;
@@ -11751,14 +11931,13 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
11751
11931
  let $to = parse.doc.resolveNoCache(change.endB - parse.from);
11752
11932
  let $fromA = doc.resolve(change.start);
11753
11933
  let inlineChange = $from.sameParent($to) && $from.parent.inlineContent && $fromA.end() >= change.endA;
11754
- let nextSel;
11755
11934
  // If this looks like the effect of pressing Enter (or was recorded
11756
11935
  // as being an iOS enter press), just dispatch an Enter key instead.
11757
11936
  if (((ios && view.input.lastIOSEnter > Date.now() - 225 &&
11758
11937
  (!inlineChange || addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P"))) ||
11759
- (!inlineChange && $from.pos < parse.doc.content.size && !$from.sameParent($to) &&
11760
- (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&
11761
- nextSel.head == $to.pos)) &&
11938
+ (!inlineChange && $from.pos < parse.doc.content.size &&
11939
+ (!$from.sameParent($to) || !$from.parent.inlineContent) &&
11940
+ $from.pos < $to.pos && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")))) &&
11762
11941
  view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
11763
11942
  view.input.lastIOSEnter = 0;
11764
11943
  return;
@@ -11793,7 +11972,26 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
11793
11972
  }, 20);
11794
11973
  }
11795
11974
  let chFrom = change.start, chTo = change.endA;
11796
- let tr, storedMarks, markChange;
11975
+ let mkTr = (base) => {
11976
+ let tr = base || view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from));
11977
+ if (parse.sel) {
11978
+ let sel = resolveSelection(view, tr.doc, parse.sel);
11979
+ // Chrome will sometimes, during composition, report the
11980
+ // selection in the wrong place. If it looks like that is
11981
+ // happening, don't update the selection.
11982
+ // Edge just doesn't move the cursor forward when you start typing
11983
+ // in an empty block or between br nodes.
11984
+ if (sel && !(chrome && view.composing && sel.empty &&
11985
+ (change.start != change.endB || view.input.lastChromeDelete < Date.now() - 100) &&
11986
+ (sel.head == chFrom || sel.head == tr.mapping.map(chTo) - 1) ||
11987
+ ie$1 && sel.empty && sel.head == chFrom))
11988
+ tr.setSelection(sel);
11989
+ }
11990
+ if (compositionID)
11991
+ tr.setMeta("composition", compositionID);
11992
+ return tr.scrollIntoView();
11993
+ };
11994
+ let markChange;
11797
11995
  if (inlineChange) {
11798
11996
  if ($from.pos == $to.pos) { // Deletion
11799
11997
  // IE11 sometimes weirdly moves the DOM selection around after
@@ -11802,46 +12000,36 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
11802
12000
  view.domObserver.suppressSelectionUpdates();
11803
12001
  setTimeout(() => selectionToDOM(view), 20);
11804
12002
  }
11805
- tr = view.state.tr.delete(chFrom, chTo);
11806
- storedMarks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA));
12003
+ let tr = mkTr(view.state.tr.delete(chFrom, chTo));
12004
+ let marks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA));
12005
+ if (marks)
12006
+ tr.ensureMarks(marks);
12007
+ view.dispatch(tr);
11807
12008
  }
11808
12009
  else if ( // Adding or removing a mark
11809
12010
  change.endA == change.endB &&
11810
12011
  (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), $fromA.parent.content.cut($fromA.parentOffset, change.endA - $fromA.start())))) {
11811
- tr = view.state.tr;
12012
+ let tr = mkTr(view.state.tr);
11812
12013
  if (markChange.type == "add")
11813
12014
  tr.addMark(chFrom, chTo, markChange.mark);
11814
12015
  else
11815
12016
  tr.removeMark(chFrom, chTo, markChange.mark);
12017
+ view.dispatch(tr);
11816
12018
  }
11817
12019
  else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) {
11818
12020
  // Both positions in the same text node -- simply insert text
11819
12021
  let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset);
11820
- if (view.someProp("handleTextInput", f => f(view, chFrom, chTo, text)))
11821
- return;
11822
- tr = view.state.tr.insertText(text, chFrom, chTo);
11823
- }
11824
- }
11825
- if (!tr)
11826
- tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from));
11827
- if (parse.sel) {
11828
- let sel = resolveSelection(view, tr.doc, parse.sel);
11829
- // Chrome will sometimes, during composition, report the
11830
- // selection in the wrong place. If it looks like that is
11831
- // happening, don't update the selection.
11832
- // Edge just doesn't move the cursor forward when you start typing
11833
- // in an empty block or between br nodes.
11834
- if (sel && !(chrome && view.composing && sel.empty &&
11835
- (change.start != change.endB || view.input.lastChromeDelete < Date.now() - 100) &&
11836
- (sel.head == chFrom || sel.head == tr.mapping.map(chTo) - 1) ||
11837
- ie$1 && sel.empty && sel.head == chFrom))
11838
- tr.setSelection(sel);
11839
- }
11840
- if (storedMarks)
11841
- tr.ensureMarks(storedMarks);
11842
- if (compositionID)
11843
- tr.setMeta("composition", compositionID);
11844
- view.dispatch(tr.scrollIntoView());
12022
+ let deflt = () => mkTr(view.state.tr.insertText(text, chFrom, chTo));
12023
+ if (!view.someProp("handleTextInput", f => f(view, chFrom, chTo, text, deflt)))
12024
+ view.dispatch(deflt());
12025
+ }
12026
+ else {
12027
+ view.dispatch(mkTr());
12028
+ }
12029
+ }
12030
+ else {
12031
+ view.dispatch(mkTr());
12032
+ }
11845
12033
  }
11846
12034
  function resolveSelection(view, doc, parsedSel) {
11847
12035
  if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size)
@@ -11993,7 +12181,7 @@ class EditorView {
11993
12181
  this.pluginViews = [];
11994
12182
  /**
11995
12183
  Holds `true` when a hack node is needed in Firefox to prevent the
11996
- [space is eaten issue](https://github.com/ProseMirror/prosemirror/issues/651)
12184
+ [space is eaten issue](https://code.haverbeke.berlin/prosemirror/prosemirror/issues/651)
11997
12185
  @internal
11998
12186
  */
11999
12187
  this.requiresGeckoHackNode = false;
@@ -12133,7 +12321,7 @@ class EditorView {
12133
12321
  this.docView.destroy();
12134
12322
  this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this);
12135
12323
  }
12136
- if (chromeKludge && !this.trackWrites)
12324
+ if (chromeKludge && (!this.trackWrites || !this.dom.contains(this.trackWrites)))
12137
12325
  forceSelUpdate = true;
12138
12326
  }
12139
12327
  // Work around for an issue where an update arriving right between
@@ -12211,12 +12399,12 @@ class EditorView {
12211
12399
  }
12212
12400
  updateDraggedNode(dragging, prev) {
12213
12401
  let sel = dragging.node, found = -1;
12214
- if (this.state.doc.nodeAt(sel.from) == sel.node) {
12402
+ if (sel.from < this.state.doc.content.size && this.state.doc.nodeAt(sel.from) == sel.node) {
12215
12403
  found = sel.from;
12216
12404
  }
12217
12405
  else {
12218
12406
  let movedPos = sel.from + (this.state.doc.content.size - prev.doc.content.size);
12219
- let moved = movedPos > 0 && this.state.doc.nodeAt(movedPos);
12407
+ let moved = movedPos > 0 && movedPos < this.state.doc.content.size && this.state.doc.nodeAt(movedPos);
12220
12408
  if (moved == sel.node)
12221
12409
  found = movedPos;
12222
12410
  }
@@ -12390,6 +12578,17 @@ class EditorView {
12390
12578
  return doPaste(this, text, null, true, event || new ClipboardEvent("paste"));
12391
12579
  }
12392
12580
  /**
12581
+ Serialize the given slice as it would be if it was copied from
12582
+ this editor. Returns a DOM element that contains a
12583
+ representation of the slice as its children, a textual
12584
+ representation, and the transformed slice (which can be
12585
+ different from the given input due to hooks like
12586
+ [`transformCopied`](https://prosemirror.net/docs/ref/#view.EditorProps.transformCopied)).
12587
+ */
12588
+ serializeForClipboard(slice) {
12589
+ return serializeForClipboard(this, slice);
12590
+ }
12591
+ /**
12393
12592
  Removes the editor from the DOM and destroys all [node
12394
12593
  views](https://prosemirror.net/docs/ref/#view.NodeView).
12395
12594
  */
@@ -12424,22 +12623,6 @@ class EditorView {
12424
12623
  return dispatchEvent(this, event);
12425
12624
  }
12426
12625
  /**
12427
- Dispatch a transaction. Will call
12428
- [`dispatchTransaction`](https://prosemirror.net/docs/ref/#view.DirectEditorProps.dispatchTransaction)
12429
- when given, and otherwise defaults to applying the transaction to
12430
- the current state and calling
12431
- [`updateState`](https://prosemirror.net/docs/ref/#view.EditorView.updateState) with the result.
12432
- This method is bound to the view instance, so that it can be
12433
- easily passed around.
12434
- */
12435
- dispatch(tr) {
12436
- let dispatchTransaction = this._props.dispatchTransaction;
12437
- if (dispatchTransaction)
12438
- dispatchTransaction.call(this, tr);
12439
- else
12440
- this.updateState(this.state.apply(tr));
12441
- }
12442
- /**
12443
12626
  @internal
12444
12627
  */
12445
12628
  domSelectionRange() {
@@ -12456,6 +12639,13 @@ class EditorView {
12456
12639
  return this.root.getSelection();
12457
12640
  }
12458
12641
  }
12642
+ EditorView.prototype.dispatch = function (tr) {
12643
+ let dispatchTransaction = this._props.dispatchTransaction;
12644
+ if (dispatchTransaction)
12645
+ dispatchTransaction.call(this, tr);
12646
+ else
12647
+ this.updateState(this.state.apply(tr));
12648
+ };
12459
12649
  function computeDocDeco(view) {
12460
12650
  let attrs = Object.create(null);
12461
12651
  attrs.class = "ProseMirror";
@@ -13076,7 +13266,8 @@ function keyName(event) {
13076
13266
  return name
13077
13267
  }
13078
13268
 
13079
- const mac$2 = typeof navigator != "undefined" ? /Mac|iP(hone|[oa]d)/.test(navigator.platform) : false;
13269
+ const mac$2 = typeof navigator != "undefined" && /Mac|iP(hone|[oa]d)/.test(navigator.platform);
13270
+ const windows = typeof navigator != "undefined" && /Win/.test(navigator.platform);
13080
13271
  function normalizeKeyName(name) {
13081
13272
  let parts = name.split(/-(?!$)/), result = parts[parts.length - 1];
13082
13273
  if (result == "Space")
@@ -13182,12 +13373,14 @@ function keydownHandler(bindings) {
13182
13373
  if (noShift && noShift(view.state, view.dispatch, view))
13183
13374
  return true;
13184
13375
  }
13185
- if ((event.shiftKey || event.altKey || event.metaKey || name.charCodeAt(0) > 127) &&
13376
+ if ((event.altKey || event.metaKey || event.ctrlKey) &&
13377
+ // Ctrl-Alt may be used for AltGr on Windows
13378
+ !(windows && event.ctrlKey && event.altKey) &&
13186
13379
  (baseName = base$1[event.keyCode]) && baseName != name) {
13187
13380
  // Try falling back to the keyCode when there's a modifier
13188
13381
  // active or the character produced isn't ASCII, and our table
13189
13382
  // produces a different name from the the keyCode. See #668,
13190
- // #1060
13383
+ // #1060, #1529.
13191
13384
  let fromCode = map[modifiers(baseName, event)];
13192
13385
  if (fromCode && fromCode(view.state, view.dispatch, view))
13193
13386
  return true;
@@ -16420,6 +16613,10 @@ function isPunctChar (ch) {
16420
16613
  return P.test(ch) || regex.test(ch)
16421
16614
  }
16422
16615
 
16616
+ function isPunctCharCode (code) {
16617
+ return isPunctChar(fromCodePoint(code))
16618
+ }
16619
+
16423
16620
  // Markdown ASCII punctuation characters.
16424
16621
  //
16425
16622
  // !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, or ~
@@ -16481,6 +16678,7 @@ function normalizeReference (str) {
16481
16678
  // (remove this when node v10 is no longer supported).
16482
16679
  //
16483
16680
  if ('ẞ'.toLowerCase() === 'Ṿ') {
16681
+ /* c8 ignore next 2 */
16484
16682
  str = str.replace(/ẞ/g, 'ß');
16485
16683
  }
16486
16684
 
@@ -16519,6 +16717,28 @@ function normalizeReference (str) {
16519
16717
  return str.toLowerCase().toUpperCase()
16520
16718
  }
16521
16719
 
16720
+ function isAsciiTrimmable (c) {
16721
+ return c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d
16722
+ }
16723
+
16724
+ // "Light" .trim() for blocks (headers, paragraphs), where unicode spaces
16725
+ // should be preserved.
16726
+ function asciiTrim (str) {
16727
+ let start = 0;
16728
+ for (; start < str.length; start++) {
16729
+ if (!isAsciiTrimmable(str.charCodeAt(start))) {
16730
+ break
16731
+ }
16732
+ }
16733
+ let end = str.length - 1;
16734
+ for (; end >= start; end--) {
16735
+ if (!isAsciiTrimmable(str.charCodeAt(end))) {
16736
+ break
16737
+ }
16738
+ }
16739
+ return str.slice(start, end + 1)
16740
+ }
16741
+
16522
16742
  // Re-export libraries commonly used in both markdown-it and its plugins,
16523
16743
  // so plugins won't have to depend on them explicitly, which reduces their
16524
16744
  // bundled size (e.g. a browser build).
@@ -16528,6 +16748,7 @@ const lib = { mdurl, ucmicro };
16528
16748
  var utils = /*#__PURE__*/Object.freeze({
16529
16749
  __proto__: null,
16530
16750
  arrayReplaceAt: arrayReplaceAt,
16751
+ asciiTrim: asciiTrim,
16531
16752
  assign: assign$1,
16532
16753
  escapeHtml: escapeHtml,
16533
16754
  escapeRE: escapeRE$1,
@@ -16535,6 +16756,7 @@ var utils = /*#__PURE__*/Object.freeze({
16535
16756
  has: has,
16536
16757
  isMdAsciiPunct: isMdAsciiPunct,
16537
16758
  isPunctChar: isPunctChar,
16759
+ isPunctCharCode: isPunctCharCode,
16538
16760
  isSpace: isSpace,
16539
16761
  isString: isString$1,
16540
16762
  isValidEntityCode: isValidEntityCode,
@@ -17898,14 +18120,36 @@ const QUOTE_TEST_RE = /['"]/;
17898
18120
  const QUOTE_RE = /['"]/g;
17899
18121
  const APOSTROPHE = '\u2019'; /* ’ */
17900
18122
 
17901
- function replaceAt (str, index, ch) {
17902
- return str.slice(0, index) + ch + str.slice(index + 1)
18123
+ function addReplacement (replacements, tokenIdx, pos, ch) {
18124
+ if (!replacements[tokenIdx]) {
18125
+ replacements[tokenIdx] = [];
18126
+ }
18127
+
18128
+ replacements[tokenIdx].push({ pos, ch });
18129
+ }
18130
+
18131
+ function applyReplacements (str, replacements) {
18132
+ let result = '';
18133
+ let lastPos = 0;
18134
+
18135
+ replacements.sort((a, b) => a.pos - b.pos);
18136
+
18137
+ for (let i = 0; i < replacements.length; i++) {
18138
+ const replacement = replacements[i];
18139
+
18140
+ result += str.slice(lastPos, replacement.pos) + replacement.ch;
18141
+ lastPos = replacement.pos + 1;
18142
+ }
18143
+
18144
+ return result + str.slice(lastPos)
17903
18145
  }
17904
18146
 
17905
18147
  function process_inlines (tokens, state) {
17906
18148
  let j;
17907
18149
 
17908
18150
  const stack = [];
18151
+ // token index -> list of replacements in the original token content
18152
+ const replacements = {};
17909
18153
 
17910
18154
  for (let i = 0; i < tokens.length; i++) {
17911
18155
  const token = tokens[i];
@@ -17919,9 +18163,9 @@ function process_inlines (tokens, state) {
17919
18163
 
17920
18164
  if (token.type !== 'text') { continue }
17921
18165
 
17922
- let text = token.content;
18166
+ const text = token.content;
17923
18167
  let pos = 0;
17924
- let max = text.length;
18168
+ const max = text.length;
17925
18169
 
17926
18170
  /* eslint no-labels:0,block-scoped-var:0 */
17927
18171
  OUTER:
@@ -17969,8 +18213,8 @@ function process_inlines (tokens, state) {
17969
18213
  }
17970
18214
  }
17971
18215
 
17972
- const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
17973
- const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
18216
+ const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
18217
+ const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
17974
18218
 
17975
18219
  const isLastWhiteSpace = isWhiteSpace(lastChar);
17976
18220
  const isNextWhiteSpace = isWhiteSpace(nextChar);
@@ -18013,7 +18257,7 @@ function process_inlines (tokens, state) {
18013
18257
  if (!canOpen && !canClose) {
18014
18258
  // middle of word
18015
18259
  if (isSingle) {
18016
- token.content = replaceAt(token.content, t.index, APOSTROPHE);
18260
+ addReplacement(replacements, i, t.index, APOSTROPHE);
18017
18261
  }
18018
18262
  continue
18019
18263
  }
@@ -18036,18 +18280,8 @@ function process_inlines (tokens, state) {
18036
18280
  closeQuote = state.md.options.quotes[1];
18037
18281
  }
18038
18282
 
18039
- // replace token.content *before* tokens[item.token].content,
18040
- // because, if they are pointing at the same token, replaceAt
18041
- // could mess up indices when quote length != 1
18042
- token.content = replaceAt(token.content, t.index, closeQuote);
18043
- tokens[item.token].content = replaceAt(
18044
- tokens[item.token].content, item.pos, openQuote);
18045
-
18046
- pos += closeQuote.length - 1;
18047
- if (item.token === i) { pos += openQuote.length - 1; }
18048
-
18049
- text = token.content;
18050
- max = text.length;
18283
+ addReplacement(replacements, i, t.index, closeQuote);
18284
+ addReplacement(replacements, item.token, item.pos, openQuote);
18051
18285
 
18052
18286
  stack.length = j;
18053
18287
  continue OUTER
@@ -18063,10 +18297,14 @@ function process_inlines (tokens, state) {
18063
18297
  level: thisLevel
18064
18298
  });
18065
18299
  } else if (canClose && isSingle) {
18066
- token.content = replaceAt(token.content, t.index, APOSTROPHE);
18300
+ addReplacement(replacements, i, t.index, APOSTROPHE);
18067
18301
  }
18068
18302
  }
18069
18303
  }
18304
+
18305
+ Object.keys(replacements).forEach(function (tokenIdx) {
18306
+ tokens[tokenIdx].content = applyReplacements(tokens[tokenIdx].content, replacements[tokenIdx]);
18307
+ });
18070
18308
  }
18071
18309
 
18072
18310
  function smartquotes (state) {
@@ -19670,11 +19908,22 @@ function html_block (state, startLine, endLine, silent) {
19670
19908
 
19671
19909
  let nextLine = startLine + 1;
19672
19910
 
19911
+ // Block types 6 and 7 (the only ones whose end condition is a blank line)
19912
+ // have `/^$/` as their closing regexp. For all other types (1-5, e.g.
19913
+ // `<!--` comments), a blank line is regular content and must not terminate
19914
+ // the block - it ends only when its closing sequence is found.
19915
+ const endsOnBlankLine = HTML_SEQUENCES[i][1].test('');
19916
+
19673
19917
  // If we are here - we detected HTML block.
19674
19918
  // Let's roll down till block end.
19675
19919
  if (!HTML_SEQUENCES[i][1].test(lineText)) {
19676
19920
  for (; nextLine < endLine; nextLine++) {
19677
- if (state.sCount[nextLine] < state.blkIndent) { break }
19921
+ if (state.sCount[nextLine] < state.blkIndent) {
19922
+ // An outdented blank line shouldn't end a block that doesn't end on a
19923
+ // blank line (e.g. a `<!--` comment inside a list item). Such blocks
19924
+ // must continue until their closing sequence regardless of indent.
19925
+ if (endsOnBlankLine || !state.isEmpty(nextLine)) { break }
19926
+ }
19678
19927
 
19679
19928
  pos = state.bMarks[nextLine] + state.tShift[nextLine];
19680
19929
  max = state.eMarks[nextLine];
@@ -19737,7 +19986,7 @@ function heading (state, startLine, endLine, silent) {
19737
19986
  token_o.map = [startLine, state.line];
19738
19987
 
19739
19988
  const token_i = state.push('inline', '', 0);
19740
- token_i.content = state.src.slice(pos, max).trim();
19989
+ token_i.content = asciiTrim(state.src.slice(pos, max));
19741
19990
  token_i.map = [startLine, state.line];
19742
19991
  token_i.children = [];
19743
19992
 
@@ -19749,6 +19998,7 @@ function heading (state, startLine, endLine, silent) {
19749
19998
 
19750
19999
  // lheading (---, ===)
19751
20000
 
20001
+
19752
20002
  function lheading (state, startLine, endLine/*, silent */) {
19753
20003
  const terminatorRules = state.md.block.ruler.getRules('paragraph');
19754
20004
 
@@ -19806,10 +20056,11 @@ function lheading (state, startLine, endLine/*, silent */) {
19806
20056
 
19807
20057
  if (!level) {
19808
20058
  // Didn't find valid underline
20059
+ state.parentType = oldParentType;
19809
20060
  return false
19810
20061
  }
19811
20062
 
19812
- const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
20063
+ const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
19813
20064
 
19814
20065
  state.line = nextLine + 1;
19815
20066
 
@@ -19832,6 +20083,7 @@ function lheading (state, startLine, endLine/*, silent */) {
19832
20083
 
19833
20084
  // Paragraph
19834
20085
 
20086
+
19835
20087
  function paragraph (state, startLine, endLine) {
19836
20088
  const terminatorRules = state.md.block.ruler.getRules('paragraph');
19837
20089
  const oldParentType = state.parentType;
@@ -19858,7 +20110,7 @@ function paragraph (state, startLine, endLine) {
19858
20110
  if (terminate) { break }
19859
20111
  }
19860
20112
 
19861
- const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
20113
+ const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
19862
20114
 
19863
20115
  state.line = nextLine;
19864
20116
 
@@ -20085,8 +20337,30 @@ StateInline.prototype.scanDelims = function (start, canSplitWord) {
20085
20337
  const max = this.posMax;
20086
20338
  const marker = this.src.charCodeAt(start);
20087
20339
 
20088
- // treat beginning of the line as a whitespace
20089
- const lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 0x20;
20340
+ // Astral characters below are combined manually, because .codePointAt()
20341
+ // does not guarantee numeric type output. And we don't wish JIT cache issues.
20342
+ // The broken surrogate pairs are evaluated as U+FFFD to prevent possible
20343
+ // crashes.
20344
+
20345
+ let lastChar;
20346
+ if (start === 0) {
20347
+ // treat beginning of the line as a whitespace
20348
+ lastChar = 0x20;
20349
+ } else if (start === 1) {
20350
+ lastChar = this.src.charCodeAt(0);
20351
+ if ((lastChar & 0xF800) === 0xD800) { lastChar = 0xFFFD; }
20352
+ } else {
20353
+ lastChar = this.src.charCodeAt(start - 1);
20354
+ if ((lastChar & 0xFC00) === 0xDC00) {
20355
+ // low surrogate => add high one, replace broken pair with U+FFFD
20356
+ const highSurr = this.src.charCodeAt(start - 2);
20357
+ lastChar = (highSurr & 0xFC00) === 0xD800
20358
+ ? 0x10000 + ((highSurr - 0xD800) << 10) + (lastChar - 0xDC00)
20359
+ : 0xFFFD;
20360
+ } else if ((lastChar & 0xFC00) === 0xD800) {
20361
+ lastChar = 0xFFFD;
20362
+ }
20363
+ }
20090
20364
 
20091
20365
  let pos = start;
20092
20366
  while (pos < max && this.src.charCodeAt(pos) === marker) { pos++; }
@@ -20094,10 +20368,19 @@ StateInline.prototype.scanDelims = function (start, canSplitWord) {
20094
20368
  const count = pos - start;
20095
20369
 
20096
20370
  // treat end of the line as a whitespace
20097
- const nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20;
20371
+ let nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20;
20372
+ if ((nextChar & 0xFC00) === 0xD800) {
20373
+ // high surrogate => add low one, replace broken pair with U+FFFD
20374
+ const lowSurr = this.src.charCodeAt(pos + 1);
20375
+ nextChar = (lowSurr & 0xFC00) === 0xDC00
20376
+ ? 0x10000 + ((nextChar - 0xD800) << 10) + (lowSurr - 0xDC00)
20377
+ : 0xFFFD;
20378
+ } else if ((nextChar & 0xFC00) === 0xDC00) {
20379
+ nextChar = 0xFFFD;
20380
+ }
20098
20381
 
20099
- const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
20100
- const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
20382
+ const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
20383
+ const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
20101
20384
 
20102
20385
  const isLastWhiteSpace = isWhiteSpace(lastChar);
20103
20386
  const isNextWhiteSpace = isWhiteSpace(nextChar);
@@ -21124,7 +21407,7 @@ function entity (state, silent) {
21124
21407
  } else {
21125
21408
  const match = state.src.slice(pos).match(NAMED_RE);
21126
21409
  if (match) {
21127
- const decoded = decodeHTML(match[0]);
21410
+ const decoded = decodeHTMLStrict(match[0]);
21128
21411
  if (decoded !== match[0]) {
21129
21412
  if (!silent) {
21130
21413
  const token = state.push('text_special', '', 0);
@@ -21786,11 +22069,6 @@ const tlds_2ch_src_re = 'a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghik
21786
22069
  // DON'T try to make PRs with changes. Extend TLDs with LinkifyIt.tlds() instead
21787
22070
  const tlds_default = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|');
21788
22071
 
21789
- function resetScanCache (self) {
21790
- self.__index__ = -1;
21791
- self.__text_cache__ = '';
21792
- }
21793
-
21794
22072
  function createValidator (re) {
21795
22073
  return function (text, pos) {
21796
22074
  const tail = text.slice(pos);
@@ -21829,8 +22107,11 @@ function compile (self) {
21829
22107
  function untpl (tpl) { return tpl.replace('%TLDS%', re.src_tlds) }
21830
22108
 
21831
22109
  re.email_fuzzy = RegExp(untpl(re.tpl_email_fuzzy), 'i');
22110
+ re.email_fuzzy_global = RegExp(untpl(re.tpl_email_fuzzy), 'ig');
21832
22111
  re.link_fuzzy = RegExp(untpl(re.tpl_link_fuzzy), 'i');
22112
+ re.link_fuzzy_global = RegExp(untpl(re.tpl_link_fuzzy), 'ig');
21833
22113
  re.link_no_ip_fuzzy = RegExp(untpl(re.tpl_link_no_ip_fuzzy), 'i');
22114
+ re.link_no_ip_fuzzy_global = RegExp(untpl(re.tpl_link_no_ip_fuzzy), 'ig');
21834
22115
  re.host_fuzzy_test = RegExp(untpl(re.tpl_host_fuzzy_test), 'i');
21835
22116
 
21836
22117
  //
@@ -21924,12 +22205,6 @@ function compile (self) {
21924
22205
  '(' + self.re.schema_test.source + ')|(' + self.re.host_fuzzy_test.source + ')|@',
21925
22206
  'i'
21926
22207
  );
21927
-
21928
- //
21929
- // Cleanup
21930
- //
21931
-
21932
- resetScanCache(self);
21933
22208
  }
21934
22209
 
21935
22210
  /**
@@ -21937,55 +22212,45 @@ function compile (self) {
21937
22212
  *
21938
22213
  * Match result. Single element of array, returned by [[LinkifyIt#match]]
21939
22214
  **/
21940
- function Match (self, shift) {
21941
- const start = self.__index__;
21942
- const end = self.__last_index__;
21943
- const text = self.__text_cache__.slice(start, end);
22215
+ function Match (text, schema, index, lastIndex) {
22216
+ const raw = text.slice(index, lastIndex);
21944
22217
 
21945
22218
  /**
21946
22219
  * Match#schema -> String
21947
22220
  *
21948
22221
  * Prefix (protocol) for matched string.
21949
22222
  **/
21950
- this.schema = self.__schema__.toLowerCase();
22223
+ this.schema = schema.toLowerCase();
21951
22224
  /**
21952
22225
  * Match#index -> Number
21953
22226
  *
21954
22227
  * First position of matched string.
21955
22228
  **/
21956
- this.index = start + shift;
22229
+ this.index = index;
21957
22230
  /**
21958
22231
  * Match#lastIndex -> Number
21959
22232
  *
21960
22233
  * Next position after matched string.
21961
22234
  **/
21962
- this.lastIndex = end + shift;
22235
+ this.lastIndex = lastIndex;
21963
22236
  /**
21964
22237
  * Match#raw -> String
21965
22238
  *
21966
22239
  * Matched string.
21967
22240
  **/
21968
- this.raw = text;
22241
+ this.raw = raw;
21969
22242
  /**
21970
22243
  * Match#text -> String
21971
22244
  *
21972
22245
  * Notmalized text of matched string.
21973
22246
  **/
21974
- this.text = text;
22247
+ this.text = raw;
21975
22248
  /**
21976
22249
  * Match#url -> String
21977
22250
  *
21978
22251
  * Normalized url of matched string.
21979
22252
  **/
21980
- this.url = text;
21981
- }
21982
-
21983
- function createMatch (self, shift) {
21984
- const match = new Match(self, shift);
21985
-
21986
- self.__compiled__[match.schema].normalize(match, self);
21987
-
21988
- return match
22253
+ this.url = raw;
21989
22254
  }
21990
22255
 
21991
22256
  /**
@@ -22040,12 +22305,6 @@ function LinkifyIt (schemas, options) {
22040
22305
 
22041
22306
  this.__opts__ = assign({}, defaultOptions, options);
22042
22307
 
22043
- // Cache last tested result. Used to skip repeating steps on next `match` call.
22044
- this.__index__ = -1;
22045
- this.__last_index__ = -1; // Next scan position
22046
- this.__schema__ = '';
22047
- this.__text_cache__ = '';
22048
-
22049
22308
  this.__schemas__ = assign({}, defaultSchemas, schemas);
22050
22309
  this.__compiled__ = {};
22051
22310
 
@@ -22087,69 +22346,38 @@ LinkifyIt.prototype.set = function set (options) {
22087
22346
  * Searches linkifiable pattern and returns `true` on success or `false` on fail.
22088
22347
  **/
22089
22348
  LinkifyIt.prototype.test = function test (text) {
22090
- // Reset scan cache
22091
- this.__text_cache__ = text;
22092
- this.__index__ = -1;
22093
-
22094
22349
  if (!text.length) { return false }
22095
22350
 
22096
- let m, ml, me, len, shift, next, re, tld_pos, at_pos;
22351
+ let m, re;
22097
22352
 
22098
22353
  // try to scan for link with schema - that's the most simple rule
22099
22354
  if (this.re.schema_test.test(text)) {
22100
22355
  re = this.re.schema_search;
22101
22356
  re.lastIndex = 0;
22102
22357
  while ((m = re.exec(text)) !== null) {
22103
- len = this.testSchemaAt(text, m[2], re.lastIndex);
22104
- if (len) {
22105
- this.__schema__ = m[2];
22106
- this.__index__ = m.index + m[1].length;
22107
- this.__last_index__ = m.index + m[0].length + len;
22108
- break
22109
- }
22358
+ if (this.testSchemaAt(text, m[2], re.lastIndex)) { return true }
22110
22359
  }
22111
22360
  }
22112
22361
 
22113
22362
  if (this.__opts__.fuzzyLink && this.__compiled__['http:']) {
22114
22363
  // guess schemaless links
22115
- tld_pos = text.search(this.re.host_fuzzy_test);
22116
- if (tld_pos >= 0) {
22117
- // if tld is located after found link - no need to check fuzzy pattern
22118
- if (this.__index__ < 0 || tld_pos < this.__index__) {
22119
- if ((ml = text.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy)) !== null) {
22120
- shift = ml.index + ml[1].length;
22121
-
22122
- if (this.__index__ < 0 || shift < this.__index__) {
22123
- this.__schema__ = '';
22124
- this.__index__ = shift;
22125
- this.__last_index__ = ml.index + ml[0].length;
22126
- }
22127
- }
22364
+ if (text.search(this.re.host_fuzzy_test) >= 0) {
22365
+ if (text.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy) !== null) {
22366
+ return true
22128
22367
  }
22129
22368
  }
22130
22369
  }
22131
22370
 
22132
22371
  if (this.__opts__.fuzzyEmail && this.__compiled__['mailto:']) {
22133
22372
  // guess schemaless emails
22134
- at_pos = text.indexOf('@');
22135
- if (at_pos >= 0) {
22373
+ if (text.indexOf('@') >= 0) {
22136
22374
  // We can't skip this check, because this cases are possible:
22137
22375
  // 192.168.1.1@gmail.com, my.in@example.com
22138
- if ((me = text.match(this.re.email_fuzzy)) !== null) {
22139
- shift = me.index + me[1].length;
22140
- next = me.index + me[0].length;
22141
-
22142
- if (this.__index__ < 0 || shift < this.__index__ ||
22143
- (shift === this.__index__ && next > this.__last_index__)) {
22144
- this.__schema__ = 'mailto:';
22145
- this.__index__ = shift;
22146
- this.__last_index__ = next;
22147
- }
22148
- }
22376
+ if (text.match(this.re.email_fuzzy) !== null) { return true }
22149
22377
  }
22150
22378
  }
22151
22379
 
22152
- return this.__index__ >= 0
22380
+ return false
22153
22381
  };
22154
22382
 
22155
22383
  /**
@@ -22198,23 +22426,88 @@ LinkifyIt.prototype.testSchemaAt = function testSchemaAt (text, schema, pos) {
22198
22426
  **/
22199
22427
  LinkifyIt.prototype.match = function match (text) {
22200
22428
  const result = [];
22201
- let shift = 0;
22429
+ const type_schemed = [];
22430
+ const type_fuzzy_link = [];
22431
+ const type_fuzzy_email = [];
22432
+ let m, len, re;
22433
+
22434
+ function choose (a, b) {
22435
+ if (!a) { return b }
22436
+ if (!b) { return a }
22437
+ if (a.index !== b.index) { return a.index < b.index ? a : b }
22438
+ return a.lastIndex >= b.lastIndex ? a : b
22439
+ }
22440
+
22441
+ if (!text.length) { return null }
22442
+
22443
+ // scan for links with schema
22444
+ if (this.re.schema_test.test(text)) {
22445
+ re = this.re.schema_search;
22446
+ re.lastIndex = 0;
22447
+ while ((m = re.exec(text)) !== null) {
22448
+ len = this.testSchemaAt(text, m[2], re.lastIndex);
22449
+ if (len) {
22450
+ type_schemed.push({
22451
+ schema: m[2],
22452
+ index: m.index + m[1].length,
22453
+ lastIndex: m.index + m[0].length + len
22454
+ });
22455
+ }
22456
+ }
22457
+ }
22458
+
22459
+ if (this.__opts__.fuzzyLink && this.__compiled__['http:']) {
22460
+ re = this.__opts__.fuzzyIP ? this.re.link_fuzzy_global : this.re.link_no_ip_fuzzy_global;
22461
+ re.lastIndex = 0;
22462
+ while ((m = re.exec(text)) !== null) {
22463
+ type_fuzzy_link.push({
22464
+ schema: '',
22465
+ index: m.index + m[1].length,
22466
+ lastIndex: m.index + m[0].length
22467
+ });
22468
+ }
22469
+ }
22202
22470
 
22203
- // Try to take previous element from cache, if .test() called before
22204
- if (this.__index__ >= 0 && this.__text_cache__ === text) {
22205
- result.push(createMatch(this, shift));
22206
- shift = this.__last_index__;
22471
+ if (this.__opts__.fuzzyEmail && this.__compiled__['mailto:']) {
22472
+ re = this.re.email_fuzzy_global;
22473
+ re.lastIndex = 0;
22474
+ while ((m = re.exec(text)) !== null) {
22475
+ type_fuzzy_email.push({
22476
+ schema: 'mailto:',
22477
+ index: m.index + m[1].length,
22478
+ lastIndex: m.index + m[0].length
22479
+ });
22480
+ }
22207
22481
  }
22208
22482
 
22209
- // Cut head if cache was used
22210
- let tail = shift ? text.slice(shift) : text;
22483
+ const indexes = [0, 0, 0];
22484
+ let lastIndex = 0;
22211
22485
 
22212
- // Scan string until end reached
22213
- while (this.test(tail)) {
22214
- result.push(createMatch(this, shift));
22486
+ for (;;) {
22487
+ const candidates = [
22488
+ type_schemed[indexes[0]],
22489
+ type_fuzzy_email[indexes[1]],
22490
+ type_fuzzy_link[indexes[2]]
22491
+ ];
22492
+
22493
+ const candidate = choose(choose(candidates[0], candidates[1]), candidates[2]);
22494
+
22495
+ if (!candidate) { break }
22496
+
22497
+ if (candidate === candidates[0]) {
22498
+ indexes[0]++;
22499
+ } else if (candidate === candidates[1]) {
22500
+ indexes[1]++;
22501
+ } else {
22502
+ indexes[2]++;
22503
+ }
22504
+
22505
+ if (candidate.index < lastIndex) { continue }
22215
22506
 
22216
- tail = tail.slice(this.__last_index__);
22217
- shift += this.__last_index__;
22507
+ const match = new Match(text, candidate.schema, candidate.index, candidate.lastIndex);
22508
+ this.__compiled__[match.schema].normalize(match, this);
22509
+ result.push(match);
22510
+ lastIndex = candidate.lastIndex;
22218
22511
  }
22219
22512
 
22220
22513
  if (result.length) {
@@ -22231,10 +22524,6 @@ LinkifyIt.prototype.match = function match (text) {
22231
22524
  * of the string, and null otherwise.
22232
22525
  **/
22233
22526
  LinkifyIt.prototype.matchAtStart = function matchAtStart (text) {
22234
- // Reset scan cache
22235
- this.__text_cache__ = text;
22236
- this.__index__ = -1;
22237
-
22238
22527
  if (!text.length) return null
22239
22528
 
22240
22529
  const m = this.re.schema_at_start.exec(text);
@@ -22243,11 +22532,10 @@ LinkifyIt.prototype.matchAtStart = function matchAtStart (text) {
22243
22532
  const len = this.testSchemaAt(text, m[2], m[0].length);
22244
22533
  if (!len) return null
22245
22534
 
22246
- this.__schema__ = m[2];
22247
- this.__index__ = m.index + m[1].length;
22248
- this.__last_index__ = m.index + m[0].length + len;
22535
+ const match = new Match(text, m[2], m.index + m[1].length, m.index + m[0].length + len);
22249
22536
 
22250
- return createMatch(this, 0)
22537
+ this.__compiled__[match.schema].normalize(match, this);
22538
+ return match
22251
22539
  };
22252
22540
 
22253
22541
  /** chainable
@@ -23299,7 +23587,7 @@ function MarkdownIt (presetName, options) {
23299
23587
  * ```javascript
23300
23588
  * var md = require('markdown-it')()
23301
23589
  * .set({ html: true, breaks: true })
23302
- * .set({ typographer, true });
23590
+ * .set({ typographer: true });
23303
23591
  * ```
23304
23592
  *
23305
23593
  * __Note:__ To achieve the best possible performance, don't modify a
@@ -24224,8 +24512,7 @@ class MarkdownSerializerState {
24224
24512
  }
24225
24513
  if (node && node.isText && marks.some(mark => {
24226
24514
  let info = this.getMark(mark.type.name);
24227
- return info && info.expelEnclosingWhitespace &&
24228
- (index == parent.childCount - 1 || !mark.isInSet(parent.child(index + 1).marks));
24515
+ return info && info.expelEnclosingWhitespace && !this.isMarkAhead(parent, index + 1, mark);
24229
24516
  })) {
24230
24517
  let [_, rest, trail] = /^(.*?)(\s*)$/m.exec(node.text);
24231
24518
  if (trail) {
@@ -24369,6 +24656,19 @@ class MarkdownSerializerState {
24369
24656
  trailing: (text.match(/(\s+)$/) || [undefined])[0]
24370
24657
  };
24371
24658
  }
24659
+ /**
24660
+ @internal
24661
+ */
24662
+ isMarkAhead(parent, index, mark) {
24663
+ for (;; index++) {
24664
+ if (index >= parent.childCount)
24665
+ return false;
24666
+ let next = parent.child(index);
24667
+ if (next.type.name != this.options.hardBreakNodeName)
24668
+ return mark.isInSet(next.marks);
24669
+ index++;
24670
+ }
24671
+ }
24372
24672
  }
24373
24673
 
24374
24674
  const imageCache = new Map();
@@ -25695,1354 +25995,1248 @@ const createTriggerPlugin = (triggerCharacters, contentConverter) => {
25695
25995
  });
25696
25996
  };
25697
25997
 
25698
- // src/index.ts
25699
-
25700
- // src/tablemap.ts
25701
- var readFromCache;
25702
- var addToCache;
25998
+ //#region src/tablemap.ts
25999
+ let readFromCache;
26000
+ let addToCache;
25703
26001
  if (typeof WeakMap != "undefined") {
25704
- let cache = /* @__PURE__ */ new WeakMap();
25705
- readFromCache = (key) => cache.get(key);
25706
- addToCache = (key, value) => {
25707
- cache.set(key, value);
25708
- return value;
25709
- };
26002
+ let cache = /* @__PURE__ */ new WeakMap();
26003
+ readFromCache = (key) => cache.get(key);
26004
+ addToCache = (key, value) => {
26005
+ cache.set(key, value);
26006
+ return value;
26007
+ };
25710
26008
  } else {
25711
- const cache = [];
25712
- const cacheSize = 10;
25713
- let cachePos = 0;
25714
- readFromCache = (key) => {
25715
- for (let i = 0; i < cache.length; i += 2)
25716
- if (cache[i] == key) return cache[i + 1];
25717
- };
25718
- addToCache = (key, value) => {
25719
- if (cachePos == cacheSize) cachePos = 0;
25720
- cache[cachePos++] = key;
25721
- return cache[cachePos++] = value;
25722
- };
26009
+ const cache = [];
26010
+ const cacheSize = 10;
26011
+ let cachePos = 0;
26012
+ readFromCache = (key) => {
26013
+ for (let i = 0; i < cache.length; i += 2) if (cache[i] == key) return cache[i + 1];
26014
+ };
26015
+ addToCache = (key, value) => {
26016
+ if (cachePos == cacheSize) cachePos = 0;
26017
+ cache[cachePos++] = key;
26018
+ return cache[cachePos++] = value;
26019
+ };
25723
26020
  }
26021
+ /**
26022
+ * A table map describes the structure of a given table. To avoid
26023
+ * recomputing them all the time, they are cached per table node. To
26024
+ * be able to do that, positions saved in the map are relative to the
26025
+ * start of the table, rather than the start of the document.
26026
+ *
26027
+ * @public
26028
+ */
25724
26029
  var TableMap = class {
25725
- constructor(width, height, map, problems) {
25726
- this.width = width;
25727
- this.height = height;
25728
- this.map = map;
25729
- this.problems = problems;
25730
- }
25731
- // Find the dimensions of the cell at the given position.
25732
- findCell(pos) {
25733
- for (let i = 0; i < this.map.length; i++) {
25734
- const curPos = this.map[i];
25735
- if (curPos != pos) continue;
25736
- const left = i % this.width;
25737
- const top = i / this.width | 0;
25738
- let right = left + 1;
25739
- let bottom = top + 1;
25740
- for (let j = 1; right < this.width && this.map[i + j] == curPos; j++) {
25741
- right++;
25742
- }
25743
- for (let j = 1; bottom < this.height && this.map[i + this.width * j] == curPos; j++) {
25744
- bottom++;
25745
- }
25746
- return { left, top, right, bottom };
25747
- }
25748
- throw new RangeError(`No cell with offset ${pos} found`);
25749
- }
25750
- // Find the left side of the cell at the given position.
25751
- colCount(pos) {
25752
- for (let i = 0; i < this.map.length; i++) {
25753
- if (this.map[i] == pos) {
25754
- return i % this.width;
25755
- }
25756
- }
25757
- throw new RangeError(`No cell with offset ${pos} found`);
25758
- }
25759
- // Find the next cell in the given direction, starting from the cell
25760
- // at `pos`, if any.
25761
- nextCell(pos, axis, dir) {
25762
- const { left, right, top, bottom } = this.findCell(pos);
25763
- if (axis == "horiz") {
25764
- if (dir < 0 ? left == 0 : right == this.width) return null;
25765
- return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
25766
- } else {
25767
- if (dir < 0 ? top == 0 : bottom == this.height) return null;
25768
- return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
25769
- }
25770
- }
25771
- // Get the rectangle spanning the two given cells.
25772
- rectBetween(a, b) {
25773
- const {
25774
- left: leftA,
25775
- right: rightA,
25776
- top: topA,
25777
- bottom: bottomA
25778
- } = this.findCell(a);
25779
- const {
25780
- left: leftB,
25781
- right: rightB,
25782
- top: topB,
25783
- bottom: bottomB
25784
- } = this.findCell(b);
25785
- return {
25786
- left: Math.min(leftA, leftB),
25787
- top: Math.min(topA, topB),
25788
- right: Math.max(rightA, rightB),
25789
- bottom: Math.max(bottomA, bottomB)
25790
- };
25791
- }
25792
- // Return the position of all cells that have the top left corner in
25793
- // the given rectangle.
25794
- cellsInRect(rect) {
25795
- const result = [];
25796
- const seen = {};
25797
- for (let row = rect.top; row < rect.bottom; row++) {
25798
- for (let col = rect.left; col < rect.right; col++) {
25799
- const index = row * this.width + col;
25800
- const pos = this.map[index];
25801
- if (seen[pos]) continue;
25802
- seen[pos] = true;
25803
- if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) {
25804
- continue;
25805
- }
25806
- result.push(pos);
25807
- }
25808
- }
25809
- return result;
25810
- }
25811
- // Return the position at which the cell at the given row and column
25812
- // starts, or would start, if a cell started there.
25813
- positionAt(row, col, table) {
25814
- for (let i = 0, rowStart = 0; ; i++) {
25815
- const rowEnd = rowStart + table.child(i).nodeSize;
25816
- if (i == row) {
25817
- let index = col + row * this.width;
25818
- const rowEndIndex = (row + 1) * this.width;
25819
- while (index < rowEndIndex && this.map[index] < rowStart) index++;
25820
- return index == rowEndIndex ? rowEnd - 1 : this.map[index];
25821
- }
25822
- rowStart = rowEnd;
25823
- }
25824
- }
25825
- // Find the table map for the given table node.
25826
- static get(table) {
25827
- return readFromCache(table) || addToCache(table, computeMap(table));
25828
- }
26030
+ constructor(width, height, map, problems) {
26031
+ this.width = width;
26032
+ this.height = height;
26033
+ this.map = map;
26034
+ this.problems = problems;
26035
+ }
26036
+ findCell(pos) {
26037
+ for (let i = 0; i < this.map.length; i++) {
26038
+ const curPos = this.map[i];
26039
+ if (curPos != pos) continue;
26040
+ const left = i % this.width;
26041
+ const top = i / this.width | 0;
26042
+ let right = left + 1;
26043
+ let bottom = top + 1;
26044
+ for (let j = 1; right < this.width && this.map[i + j] == curPos; j++) right++;
26045
+ for (let j = 1; bottom < this.height && this.map[i + this.width * j] == curPos; j++) bottom++;
26046
+ return {
26047
+ left,
26048
+ top,
26049
+ right,
26050
+ bottom
26051
+ };
26052
+ }
26053
+ throw new RangeError(`No cell with offset ${pos} found`);
26054
+ }
26055
+ colCount(pos) {
26056
+ for (let i = 0; i < this.map.length; i++) if (this.map[i] == pos) return i % this.width;
26057
+ throw new RangeError(`No cell with offset ${pos} found`);
26058
+ }
26059
+ nextCell(pos, axis, dir) {
26060
+ const { left, right, top, bottom } = this.findCell(pos);
26061
+ if (axis == "horiz") {
26062
+ if (dir < 0 ? left == 0 : right == this.width) return null;
26063
+ return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
26064
+ } else {
26065
+ if (dir < 0 ? top == 0 : bottom == this.height) return null;
26066
+ return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
26067
+ }
26068
+ }
26069
+ rectBetween(a, b) {
26070
+ const { left: leftA, right: rightA, top: topA, bottom: bottomA } = this.findCell(a);
26071
+ const { left: leftB, right: rightB, top: topB, bottom: bottomB } = this.findCell(b);
26072
+ return {
26073
+ left: Math.min(leftA, leftB),
26074
+ top: Math.min(topA, topB),
26075
+ right: Math.max(rightA, rightB),
26076
+ bottom: Math.max(bottomA, bottomB)
26077
+ };
26078
+ }
26079
+ cellsInRect(rect) {
26080
+ const result = [];
26081
+ const seen = {};
26082
+ for (let row = rect.top; row < rect.bottom; row++) for (let col = rect.left; col < rect.right; col++) {
26083
+ const index = row * this.width + col;
26084
+ const pos = this.map[index];
26085
+ if (seen[pos]) continue;
26086
+ seen[pos] = true;
26087
+ if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) continue;
26088
+ result.push(pos);
26089
+ }
26090
+ return result;
26091
+ }
26092
+ positionAt(row, col, table) {
26093
+ for (let i = 0, rowStart = 0;; i++) {
26094
+ const rowEnd = rowStart + table.child(i).nodeSize;
26095
+ if (i == row) {
26096
+ let index = col + row * this.width;
26097
+ const rowEndIndex = (row + 1) * this.width;
26098
+ while (index < rowEndIndex && this.map[index] < rowStart) index++;
26099
+ return index == rowEndIndex ? rowEnd - 1 : this.map[index];
26100
+ }
26101
+ rowStart = rowEnd;
26102
+ }
26103
+ }
26104
+ static get(table) {
26105
+ return readFromCache(table) || addToCache(table, computeMap(table));
26106
+ }
25829
26107
  };
25830
26108
  function computeMap(table) {
25831
- if (table.type.spec.tableRole != "table")
25832
- throw new RangeError("Not a table node: " + table.type.name);
25833
- const width = findWidth(table), height = table.childCount;
25834
- const map = [];
25835
- let mapPos = 0;
25836
- let problems = null;
25837
- const colWidths = [];
25838
- for (let i = 0, e = width * height; i < e; i++) map[i] = 0;
25839
- for (let row = 0, pos = 0; row < height; row++) {
25840
- const rowNode = table.child(row);
25841
- pos++;
25842
- for (let i = 0; ; i++) {
25843
- while (mapPos < map.length && map[mapPos] != 0) mapPos++;
25844
- if (i == rowNode.childCount) break;
25845
- const cellNode = rowNode.child(i);
25846
- const { colspan, rowspan, colwidth } = cellNode.attrs;
25847
- for (let h = 0; h < rowspan; h++) {
25848
- if (h + row >= height) {
25849
- (problems || (problems = [])).push({
25850
- type: "overlong_rowspan",
25851
- pos,
25852
- n: rowspan - h
25853
- });
25854
- break;
25855
- }
25856
- const start = mapPos + h * width;
25857
- for (let w = 0; w < colspan; w++) {
25858
- if (map[start + w] == 0) map[start + w] = pos;
25859
- else
25860
- (problems || (problems = [])).push({
25861
- type: "collision",
25862
- row,
25863
- pos,
25864
- n: colspan - w
25865
- });
25866
- const colW = colwidth && colwidth[w];
25867
- if (colW) {
25868
- const widthIndex = (start + w) % width * 2, prev = colWidths[widthIndex];
25869
- if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) {
25870
- colWidths[widthIndex] = colW;
25871
- colWidths[widthIndex + 1] = 1;
25872
- } else if (prev == colW) {
25873
- colWidths[widthIndex + 1]++;
25874
- }
25875
- }
25876
- }
25877
- }
25878
- mapPos += colspan;
25879
- pos += cellNode.nodeSize;
25880
- }
25881
- const expectedPos = (row + 1) * width;
25882
- let missing = 0;
25883
- while (mapPos < expectedPos) if (map[mapPos++] == 0) missing++;
25884
- if (missing)
25885
- (problems || (problems = [])).push({ type: "missing", row, n: missing });
25886
- pos++;
25887
- }
25888
- if (width === 0 || height === 0)
25889
- (problems || (problems = [])).push({ type: "zero_sized" });
25890
- const tableMap = new TableMap(width, height, map, problems);
25891
- let badWidths = false;
25892
- for (let i = 0; !badWidths && i < colWidths.length; i += 2)
25893
- if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true;
25894
- if (badWidths) findBadColWidths(tableMap, colWidths, table);
25895
- return tableMap;
26109
+ if (table.type.spec.tableRole != "table") throw new RangeError("Not a table node: " + table.type.name);
26110
+ const width = findWidth(table), height = table.childCount;
26111
+ const map = [];
26112
+ let mapPos = 0;
26113
+ let problems = null;
26114
+ const colWidths = [];
26115
+ for (let i = 0, e = width * height; i < e; i++) map[i] = 0;
26116
+ for (let row = 0, pos = 0; row < height; row++) {
26117
+ const rowNode = table.child(row);
26118
+ pos++;
26119
+ for (let i = 0;; i++) {
26120
+ while (mapPos < map.length && map[mapPos] != 0) mapPos++;
26121
+ if (i == rowNode.childCount) break;
26122
+ const cellNode = rowNode.child(i);
26123
+ const { colspan, rowspan, colwidth } = cellNode.attrs;
26124
+ for (let h = 0; h < rowspan; h++) {
26125
+ if (h + row >= height) {
26126
+ (problems || (problems = [])).push({
26127
+ type: "overlong_rowspan",
26128
+ pos,
26129
+ n: rowspan - h
26130
+ });
26131
+ break;
26132
+ }
26133
+ const start = mapPos + h * width;
26134
+ for (let w = 0; w < colspan; w++) {
26135
+ if (map[start + w] == 0) map[start + w] = pos;
26136
+ else (problems || (problems = [])).push({
26137
+ type: "collision",
26138
+ row,
26139
+ pos,
26140
+ n: colspan - w
26141
+ });
26142
+ const colW = colwidth && colwidth[w];
26143
+ if (colW) {
26144
+ const widthIndex = (start + w) % width * 2, prev = colWidths[widthIndex];
26145
+ if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) {
26146
+ colWidths[widthIndex] = colW;
26147
+ colWidths[widthIndex + 1] = 1;
26148
+ } else if (prev == colW) colWidths[widthIndex + 1]++;
26149
+ }
26150
+ }
26151
+ }
26152
+ mapPos += colspan;
26153
+ pos += cellNode.nodeSize;
26154
+ }
26155
+ const expectedPos = (row + 1) * width;
26156
+ let missing = 0;
26157
+ while (mapPos < expectedPos) if (map[mapPos++] == 0) missing++;
26158
+ if (missing) (problems || (problems = [])).push({
26159
+ type: "missing",
26160
+ row,
26161
+ n: missing
26162
+ });
26163
+ pos++;
26164
+ }
26165
+ if (width === 0 || height === 0) (problems || (problems = [])).push({ type: "zero_sized" });
26166
+ const tableMap = new TableMap(width, height, map, problems);
26167
+ let badWidths = false;
26168
+ for (let i = 0; !badWidths && i < colWidths.length; i += 2) if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true;
26169
+ if (badWidths) findBadColWidths(tableMap, colWidths, table);
26170
+ return tableMap;
25896
26171
  }
25897
26172
  function findWidth(table) {
25898
- let width = -1;
25899
- let hasRowSpan = false;
25900
- for (let row = 0; row < table.childCount; row++) {
25901
- const rowNode = table.child(row);
25902
- let rowWidth = 0;
25903
- if (hasRowSpan)
25904
- for (let j = 0; j < row; j++) {
25905
- const prevRow = table.child(j);
25906
- for (let i = 0; i < prevRow.childCount; i++) {
25907
- const cell = prevRow.child(i);
25908
- if (j + cell.attrs.rowspan > row) rowWidth += cell.attrs.colspan;
25909
- }
25910
- }
25911
- for (let i = 0; i < rowNode.childCount; i++) {
25912
- const cell = rowNode.child(i);
25913
- rowWidth += cell.attrs.colspan;
25914
- if (cell.attrs.rowspan > 1) hasRowSpan = true;
25915
- }
25916
- if (width == -1) width = rowWidth;
25917
- else if (width != rowWidth) width = Math.max(width, rowWidth);
25918
- }
25919
- return width;
26173
+ let width = -1;
26174
+ let hasRowSpan = false;
26175
+ for (let row = 0; row < table.childCount; row++) {
26176
+ const rowNode = table.child(row);
26177
+ let rowWidth = 0;
26178
+ if (hasRowSpan) for (let j = 0; j < row; j++) {
26179
+ const prevRow = table.child(j);
26180
+ for (let i = 0; i < prevRow.childCount; i++) {
26181
+ const cell = prevRow.child(i);
26182
+ if (j + cell.attrs.rowspan > row) rowWidth += cell.attrs.colspan;
26183
+ }
26184
+ }
26185
+ for (let i = 0; i < rowNode.childCount; i++) {
26186
+ const cell = rowNode.child(i);
26187
+ rowWidth += cell.attrs.colspan;
26188
+ if (cell.attrs.rowspan > 1) hasRowSpan = true;
26189
+ }
26190
+ if (width == -1) width = rowWidth;
26191
+ else if (width != rowWidth) width = Math.max(width, rowWidth);
26192
+ }
26193
+ return width;
25920
26194
  }
25921
26195
  function findBadColWidths(map, colWidths, table) {
25922
- if (!map.problems) map.problems = [];
25923
- const seen = {};
25924
- for (let i = 0; i < map.map.length; i++) {
25925
- const pos = map.map[i];
25926
- if (seen[pos]) continue;
25927
- seen[pos] = true;
25928
- const node = table.nodeAt(pos);
25929
- if (!node) {
25930
- throw new RangeError(`No cell with offset ${pos} found`);
25931
- }
25932
- let updated = null;
25933
- const attrs = node.attrs;
25934
- for (let j = 0; j < attrs.colspan; j++) {
25935
- const col = (i + j) % map.width;
25936
- const colWidth = colWidths[col * 2];
25937
- if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j] != colWidth))
25938
- (updated || (updated = freshColWidth(attrs)))[j] = colWidth;
25939
- }
25940
- if (updated)
25941
- map.problems.unshift({
25942
- type: "colwidth mismatch",
25943
- pos,
25944
- colwidth: updated
25945
- });
25946
- }
26196
+ if (!map.problems) map.problems = [];
26197
+ const seen = {};
26198
+ for (let i = 0; i < map.map.length; i++) {
26199
+ const pos = map.map[i];
26200
+ if (seen[pos]) continue;
26201
+ seen[pos] = true;
26202
+ const node = table.nodeAt(pos);
26203
+ if (!node) throw new RangeError(`No cell with offset ${pos} found`);
26204
+ let updated = null;
26205
+ const attrs = node.attrs;
26206
+ for (let j = 0; j < attrs.colspan; j++) {
26207
+ const colWidth = colWidths[(i + j) % map.width * 2];
26208
+ if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j] != colWidth)) (updated || (updated = freshColWidth(attrs)))[j] = colWidth;
26209
+ }
26210
+ if (updated) map.problems.unshift({
26211
+ type: "colwidth mismatch",
26212
+ pos,
26213
+ colwidth: updated
26214
+ });
26215
+ }
25947
26216
  }
25948
26217
  function freshColWidth(attrs) {
25949
- if (attrs.colwidth) return attrs.colwidth.slice();
25950
- const result = [];
25951
- for (let i = 0; i < attrs.colspan; i++) result.push(0);
25952
- return result;
26218
+ if (attrs.colwidth) return attrs.colwidth.slice();
26219
+ const result = [];
26220
+ for (let i = 0; i < attrs.colspan; i++) result.push(0);
26221
+ return result;
25953
26222
  }
25954
26223
 
25955
- // src/schema.ts
26224
+ //#endregion
26225
+ //#region src/schema.ts
25956
26226
  function getCellAttrs(dom, extraAttrs) {
25957
- if (typeof dom === "string") {
25958
- return {};
25959
- }
25960
- const widthAttr = dom.getAttribute("data-colwidth");
25961
- const widths = widthAttr && /^\d+(,\d+)*$/.test(widthAttr) ? widthAttr.split(",").map((s) => Number(s)) : null;
25962
- const colspan = Number(dom.getAttribute("colspan") || 1);
25963
- const result = {
25964
- colspan,
25965
- rowspan: Number(dom.getAttribute("rowspan") || 1),
25966
- colwidth: widths && widths.length == colspan ? widths : null
25967
- };
25968
- for (const prop in extraAttrs) {
25969
- const getter = extraAttrs[prop].getFromDOM;
25970
- const value = getter && getter(dom);
25971
- if (value != null) {
25972
- result[prop] = value;
25973
- }
25974
- }
25975
- return result;
26227
+ if (typeof dom === "string") return {};
26228
+ const widthAttr = dom.getAttribute("data-colwidth");
26229
+ const widths = widthAttr && /^\d+(,\d+)*$/.test(widthAttr) ? widthAttr.split(",").map((s) => Number(s)) : null;
26230
+ const colspan = Number(dom.getAttribute("colspan") || 1);
26231
+ const result = {
26232
+ colspan,
26233
+ rowspan: Number(dom.getAttribute("rowspan") || 1),
26234
+ colwidth: widths && widths.length == colspan ? widths : null
26235
+ };
26236
+ for (const prop in extraAttrs) {
26237
+ const getter = extraAttrs[prop].getFromDOM;
26238
+ const value = getter && getter(dom);
26239
+ if (value != null) result[prop] = value;
26240
+ }
26241
+ return result;
25976
26242
  }
25977
26243
  function setCellAttrs(node, extraAttrs) {
25978
- const attrs = {};
25979
- if (node.attrs.colspan != 1) attrs.colspan = node.attrs.colspan;
25980
- if (node.attrs.rowspan != 1) attrs.rowspan = node.attrs.rowspan;
25981
- if (node.attrs.colwidth)
25982
- attrs["data-colwidth"] = node.attrs.colwidth.join(",");
25983
- for (const prop in extraAttrs) {
25984
- const setter = extraAttrs[prop].setDOMAttr;
25985
- if (setter) setter(node.attrs[prop], attrs);
25986
- }
25987
- return attrs;
26244
+ const attrs = {};
26245
+ if (node.attrs.colspan != 1) attrs.colspan = node.attrs.colspan;
26246
+ if (node.attrs.rowspan != 1) attrs.rowspan = node.attrs.rowspan;
26247
+ if (node.attrs.colwidth) attrs["data-colwidth"] = node.attrs.colwidth.join(",");
26248
+ for (const prop in extraAttrs) {
26249
+ const setter = extraAttrs[prop].setDOMAttr;
26250
+ if (setter) setter(node.attrs[prop], attrs);
26251
+ }
26252
+ return attrs;
25988
26253
  }
26254
+ function validateColwidth(value) {
26255
+ if (value === null) return;
26256
+ if (!Array.isArray(value)) throw new TypeError("colwidth must be null or an array");
26257
+ for (const item of value) if (typeof item !== "number") throw new TypeError("colwidth must be null or an array of numbers");
26258
+ }
26259
+ /**
26260
+ * This function creates a set of [node
26261
+ * specs](http://prosemirror.net/docs/ref/#model.SchemaSpec.nodes) for
26262
+ * `table`, `table_row`, and `table_cell` nodes types as used by this
26263
+ * module. The result can then be added to the set of nodes when
26264
+ * creating a schema.
26265
+ *
26266
+ * @public
26267
+ */
25989
26268
  function tableNodes(options) {
25990
- const extraAttrs = options.cellAttributes || {};
25991
- const cellAttrs = {
25992
- colspan: { default: 1 },
25993
- rowspan: { default: 1 },
25994
- colwidth: { default: null }
25995
- };
25996
- for (const prop in extraAttrs)
25997
- cellAttrs[prop] = { default: extraAttrs[prop].default };
25998
- return {
25999
- table: {
26000
- content: "table_row+",
26001
- tableRole: "table",
26002
- isolating: true,
26003
- group: options.tableGroup,
26004
- parseDOM: [{ tag: "table" }],
26005
- toDOM() {
26006
- return ["table", ["tbody", 0]];
26007
- }
26008
- },
26009
- table_row: {
26010
- content: "(table_cell | table_header)*",
26011
- tableRole: "row",
26012
- parseDOM: [{ tag: "tr" }],
26013
- toDOM() {
26014
- return ["tr", 0];
26015
- }
26016
- },
26017
- table_cell: {
26018
- content: options.cellContent,
26019
- attrs: cellAttrs,
26020
- tableRole: "cell",
26021
- isolating: true,
26022
- parseDOM: [
26023
- { tag: "td", getAttrs: (dom) => getCellAttrs(dom, extraAttrs) }
26024
- ],
26025
- toDOM(node) {
26026
- return ["td", setCellAttrs(node, extraAttrs), 0];
26027
- }
26028
- },
26029
- table_header: {
26030
- content: options.cellContent,
26031
- attrs: cellAttrs,
26032
- tableRole: "header_cell",
26033
- isolating: true,
26034
- parseDOM: [
26035
- { tag: "th", getAttrs: (dom) => getCellAttrs(dom, extraAttrs) }
26036
- ],
26037
- toDOM(node) {
26038
- return ["th", setCellAttrs(node, extraAttrs), 0];
26039
- }
26040
- }
26041
- };
26269
+ const extraAttrs = options.cellAttributes || {};
26270
+ const cellAttrs = {
26271
+ colspan: {
26272
+ default: 1,
26273
+ validate: "number"
26274
+ },
26275
+ rowspan: {
26276
+ default: 1,
26277
+ validate: "number"
26278
+ },
26279
+ colwidth: {
26280
+ default: null,
26281
+ validate: validateColwidth
26282
+ }
26283
+ };
26284
+ for (const prop in extraAttrs) cellAttrs[prop] = {
26285
+ default: extraAttrs[prop].default,
26286
+ validate: extraAttrs[prop].validate
26287
+ };
26288
+ return {
26289
+ table: {
26290
+ content: "table_row+",
26291
+ tableRole: "table",
26292
+ isolating: true,
26293
+ group: options.tableGroup,
26294
+ parseDOM: [{ tag: "table" }],
26295
+ toDOM() {
26296
+ return ["table", ["tbody", 0]];
26297
+ }
26298
+ },
26299
+ table_row: {
26300
+ content: "(table_cell | table_header)*",
26301
+ tableRole: "row",
26302
+ parseDOM: [{ tag: "tr" }],
26303
+ toDOM() {
26304
+ return ["tr", 0];
26305
+ }
26306
+ },
26307
+ table_cell: {
26308
+ content: options.cellContent,
26309
+ attrs: cellAttrs,
26310
+ tableRole: "cell",
26311
+ isolating: true,
26312
+ parseDOM: [{
26313
+ tag: "td",
26314
+ getAttrs: (dom) => getCellAttrs(dom, extraAttrs)
26315
+ }],
26316
+ toDOM(node) {
26317
+ return [
26318
+ "td",
26319
+ setCellAttrs(node, extraAttrs),
26320
+ 0
26321
+ ];
26322
+ }
26323
+ },
26324
+ table_header: {
26325
+ content: options.cellContent,
26326
+ attrs: cellAttrs,
26327
+ tableRole: "header_cell",
26328
+ isolating: true,
26329
+ parseDOM: [{
26330
+ tag: "th",
26331
+ getAttrs: (dom) => getCellAttrs(dom, extraAttrs)
26332
+ }],
26333
+ toDOM(node) {
26334
+ return [
26335
+ "th",
26336
+ setCellAttrs(node, extraAttrs),
26337
+ 0
26338
+ ];
26339
+ }
26340
+ }
26341
+ };
26042
26342
  }
26343
+ /**
26344
+ * @public
26345
+ */
26043
26346
  function tableNodeTypes(schema) {
26044
- let result = schema.cached.tableNodeTypes;
26045
- if (!result) {
26046
- result = schema.cached.tableNodeTypes = {};
26047
- for (const name in schema.nodes) {
26048
- const type = schema.nodes[name], role = type.spec.tableRole;
26049
- if (role) result[role] = type;
26050
- }
26051
- }
26052
- return result;
26347
+ let result = schema.cached.tableNodeTypes;
26348
+ if (!result) {
26349
+ result = schema.cached.tableNodeTypes = {};
26350
+ for (const name in schema.nodes) {
26351
+ const type = schema.nodes[name], role = type.spec.tableRole;
26352
+ if (role) result[role] = type;
26353
+ }
26354
+ }
26355
+ return result;
26053
26356
  }
26054
26357
 
26055
- // src/util.ts
26056
- var tableEditingKey = new PluginKey("selectingCells");
26358
+ //#endregion
26359
+ //#region src/util.ts
26360
+ /**
26361
+ * @public
26362
+ */
26363
+ const tableEditingKey = new PluginKey("selectingCells");
26364
+ /**
26365
+ * @public
26366
+ */
26057
26367
  function cellAround($pos) {
26058
- for (let d = $pos.depth - 1; d > 0; d--)
26059
- if ($pos.node(d).type.spec.tableRole == "row")
26060
- return $pos.node(0).resolve($pos.before(d + 1));
26061
- return null;
26368
+ for (let d = $pos.depth - 1; d > 0; d--) if ($pos.node(d).type.spec.tableRole == "row") return $pos.node(0).resolve($pos.before(d + 1));
26369
+ return null;
26062
26370
  }
26371
+ /**
26372
+ * @public
26373
+ */
26063
26374
  function isInTable(state) {
26064
- const $head = state.selection.$head;
26065
- for (let d = $head.depth; d > 0; d--)
26066
- if ($head.node(d).type.spec.tableRole == "row") return true;
26067
- return false;
26375
+ const $head = state.selection.$head;
26376
+ for (let d = $head.depth; d > 0; d--) if ($head.node(d).type.spec.tableRole == "row") return true;
26377
+ return false;
26068
26378
  }
26379
+ /**
26380
+ * @internal
26381
+ */
26069
26382
  function selectionCell(state) {
26070
- const sel = state.selection;
26071
- if ("$anchorCell" in sel && sel.$anchorCell) {
26072
- return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell;
26073
- } else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") {
26074
- return sel.$anchor;
26075
- }
26076
- const $cell = cellAround(sel.$head) || cellNear(sel.$head);
26077
- if ($cell) {
26078
- return $cell;
26079
- }
26080
- throw new RangeError(`No cell found around position ${sel.head}`);
26383
+ const sel = state.selection;
26384
+ if ("$anchorCell" in sel && sel.$anchorCell) return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell;
26385
+ else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") return sel.$anchor;
26386
+ const $cell = cellAround(sel.$head) || cellNear(sel.$head);
26387
+ if ($cell) return $cell;
26388
+ throw new RangeError(`No cell found around position ${sel.head}`);
26081
26389
  }
26390
+ /**
26391
+ * @public
26392
+ */
26082
26393
  function cellNear($pos) {
26083
- for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) {
26084
- const role = after.type.spec.tableRole;
26085
- if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos);
26086
- }
26087
- for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) {
26088
- const role = before.type.spec.tableRole;
26089
- if (role == "cell" || role == "header_cell")
26090
- return $pos.doc.resolve(pos - before.nodeSize);
26091
- }
26394
+ for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) {
26395
+ const role = after.type.spec.tableRole;
26396
+ if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos);
26397
+ }
26398
+ for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) {
26399
+ const role = before.type.spec.tableRole;
26400
+ if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos - before.nodeSize);
26401
+ }
26092
26402
  }
26403
+ /**
26404
+ * @public
26405
+ */
26093
26406
  function pointsAtCell($pos) {
26094
- return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter;
26407
+ return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter;
26095
26408
  }
26409
+ /**
26410
+ * @internal
26411
+ */
26096
26412
  function inSameTable($cellA, $cellB) {
26097
- return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1);
26413
+ return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1);
26098
26414
  }
26415
+ /**
26416
+ * @public
26417
+ */
26099
26418
  function nextCell($pos, axis, dir) {
26100
- const table = $pos.node(-1);
26101
- const map = TableMap.get(table);
26102
- const tableStart = $pos.start(-1);
26103
- const moved = map.nextCell($pos.pos - tableStart, axis, dir);
26104
- return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
26419
+ const table = $pos.node(-1);
26420
+ const map = TableMap.get(table);
26421
+ const tableStart = $pos.start(-1);
26422
+ const moved = map.nextCell($pos.pos - tableStart, axis, dir);
26423
+ return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
26105
26424
  }
26425
+ /**
26426
+ * @public
26427
+ */
26106
26428
  function removeColSpan(attrs, pos, n = 1) {
26107
- const result = { ...attrs, colspan: attrs.colspan - n };
26108
- if (result.colwidth) {
26109
- result.colwidth = result.colwidth.slice();
26110
- result.colwidth.splice(pos, n);
26111
- if (!result.colwidth.some((w) => w > 0)) result.colwidth = null;
26112
- }
26113
- return result;
26114
- }
26115
-
26116
- // src/cellselection.ts
26117
- var CellSelection = class _CellSelection extends Selection {
26118
- // A table selection is identified by its anchor and head cells. The
26119
- // positions given to this constructor should point _before_ two
26120
- // cells in the same table. They may be the same, to select a single
26121
- // cell.
26122
- constructor($anchorCell, $headCell = $anchorCell) {
26123
- const table = $anchorCell.node(-1);
26124
- const map = TableMap.get(table);
26125
- const tableStart = $anchorCell.start(-1);
26126
- const rect = map.rectBetween(
26127
- $anchorCell.pos - tableStart,
26128
- $headCell.pos - tableStart
26129
- );
26130
- const doc = $anchorCell.node(0);
26131
- const cells = map.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart);
26132
- cells.unshift($headCell.pos - tableStart);
26133
- const ranges = cells.map((pos) => {
26134
- const cell = table.nodeAt(pos);
26135
- if (!cell) {
26136
- throw RangeError(`No cell with offset ${pos} found`);
26137
- }
26138
- const from = tableStart + pos + 1;
26139
- return new SelectionRange(
26140
- doc.resolve(from),
26141
- doc.resolve(from + cell.content.size)
26142
- );
26143
- });
26144
- super(ranges[0].$from, ranges[0].$to, ranges);
26145
- this.$anchorCell = $anchorCell;
26146
- this.$headCell = $headCell;
26147
- }
26148
- map(doc, mapping) {
26149
- const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
26150
- const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
26151
- if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
26152
- const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1);
26153
- if (tableChanged && this.isRowSelection())
26154
- return _CellSelection.rowSelection($anchorCell, $headCell);
26155
- else if (tableChanged && this.isColSelection())
26156
- return _CellSelection.colSelection($anchorCell, $headCell);
26157
- else return new _CellSelection($anchorCell, $headCell);
26158
- }
26159
- return TextSelection.between($anchorCell, $headCell);
26160
- }
26161
- // Returns a rectangular slice of table rows containing the selected
26162
- // cells.
26163
- content() {
26164
- const table = this.$anchorCell.node(-1);
26165
- const map = TableMap.get(table);
26166
- const tableStart = this.$anchorCell.start(-1);
26167
- const rect = map.rectBetween(
26168
- this.$anchorCell.pos - tableStart,
26169
- this.$headCell.pos - tableStart
26170
- );
26171
- const seen = {};
26172
- const rows = [];
26173
- for (let row = rect.top; row < rect.bottom; row++) {
26174
- const rowContent = [];
26175
- for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
26176
- const pos = map.map[index];
26177
- if (seen[pos]) continue;
26178
- seen[pos] = true;
26179
- const cellRect = map.findCell(pos);
26180
- let cell = table.nodeAt(pos);
26181
- if (!cell) {
26182
- throw RangeError(`No cell with offset ${pos} found`);
26183
- }
26184
- const extraLeft = rect.left - cellRect.left;
26185
- const extraRight = cellRect.right - rect.right;
26186
- if (extraLeft > 0 || extraRight > 0) {
26187
- let attrs = cell.attrs;
26188
- if (extraLeft > 0) {
26189
- attrs = removeColSpan(attrs, 0, extraLeft);
26190
- }
26191
- if (extraRight > 0) {
26192
- attrs = removeColSpan(
26193
- attrs,
26194
- attrs.colspan - extraRight,
26195
- extraRight
26196
- );
26197
- }
26198
- if (cellRect.left < rect.left) {
26199
- cell = cell.type.createAndFill(attrs);
26200
- if (!cell) {
26201
- throw RangeError(
26202
- `Could not create cell with attrs ${JSON.stringify(attrs)}`
26203
- );
26204
- }
26205
- } else {
26206
- cell = cell.type.create(attrs, cell.content);
26207
- }
26208
- }
26209
- if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
26210
- const attrs = {
26211
- ...cell.attrs,
26212
- rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
26213
- };
26214
- if (cellRect.top < rect.top) {
26215
- cell = cell.type.createAndFill(attrs);
26216
- } else {
26217
- cell = cell.type.create(attrs, cell.content);
26218
- }
26219
- }
26220
- rowContent.push(cell);
26221
- }
26222
- rows.push(table.child(row).copy(Fragment.from(rowContent)));
26223
- }
26224
- const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
26225
- return new Slice(Fragment.from(fragment), 1, 1);
26226
- }
26227
- replace(tr, content = Slice.empty) {
26228
- const mapFrom = tr.steps.length, ranges = this.ranges;
26229
- for (let i = 0; i < ranges.length; i++) {
26230
- const { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
26231
- tr.replace(
26232
- mapping.map($from.pos),
26233
- mapping.map($to.pos),
26234
- i ? Slice.empty : content
26235
- );
26236
- }
26237
- const sel = Selection.findFrom(
26238
- tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)),
26239
- -1
26240
- );
26241
- if (sel) tr.setSelection(sel);
26242
- }
26243
- replaceWith(tr, node) {
26244
- this.replace(tr, new Slice(Fragment.from(node), 0, 0));
26245
- }
26246
- forEachCell(f) {
26247
- const table = this.$anchorCell.node(-1);
26248
- const map = TableMap.get(table);
26249
- const tableStart = this.$anchorCell.start(-1);
26250
- const cells = map.cellsInRect(
26251
- map.rectBetween(
26252
- this.$anchorCell.pos - tableStart,
26253
- this.$headCell.pos - tableStart
26254
- )
26255
- );
26256
- for (let i = 0; i < cells.length; i++) {
26257
- f(table.nodeAt(cells[i]), tableStart + cells[i]);
26258
- }
26259
- }
26260
- // True if this selection goes all the way from the top to the
26261
- // bottom of the table.
26262
- isColSelection() {
26263
- const anchorTop = this.$anchorCell.index(-1);
26264
- const headTop = this.$headCell.index(-1);
26265
- if (Math.min(anchorTop, headTop) > 0) return false;
26266
- const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
26267
- const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan;
26268
- return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount;
26269
- }
26270
- // Returns the smallest column selection that covers the given anchor
26271
- // and head cell.
26272
- static colSelection($anchorCell, $headCell = $anchorCell) {
26273
- const table = $anchorCell.node(-1);
26274
- const map = TableMap.get(table);
26275
- const tableStart = $anchorCell.start(-1);
26276
- const anchorRect = map.findCell($anchorCell.pos - tableStart);
26277
- const headRect = map.findCell($headCell.pos - tableStart);
26278
- const doc = $anchorCell.node(0);
26279
- if (anchorRect.top <= headRect.top) {
26280
- if (anchorRect.top > 0)
26281
- $anchorCell = doc.resolve(tableStart + map.map[anchorRect.left]);
26282
- if (headRect.bottom < map.height)
26283
- $headCell = doc.resolve(
26284
- tableStart + map.map[map.width * (map.height - 1) + headRect.right - 1]
26285
- );
26286
- } else {
26287
- if (headRect.top > 0)
26288
- $headCell = doc.resolve(tableStart + map.map[headRect.left]);
26289
- if (anchorRect.bottom < map.height)
26290
- $anchorCell = doc.resolve(
26291
- tableStart + map.map[map.width * (map.height - 1) + anchorRect.right - 1]
26292
- );
26293
- }
26294
- return new _CellSelection($anchorCell, $headCell);
26295
- }
26296
- // True if this selection goes all the way from the left to the
26297
- // right of the table.
26298
- isRowSelection() {
26299
- const table = this.$anchorCell.node(-1);
26300
- const map = TableMap.get(table);
26301
- const tableStart = this.$anchorCell.start(-1);
26302
- const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
26303
- const headLeft = map.colCount(this.$headCell.pos - tableStart);
26304
- if (Math.min(anchorLeft, headLeft) > 0) return false;
26305
- const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
26306
- const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
26307
- return Math.max(anchorRight, headRight) == map.width;
26308
- }
26309
- eq(other) {
26310
- return other instanceof _CellSelection && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos;
26311
- }
26312
- // Returns the smallest row selection that covers the given anchor
26313
- // and head cell.
26314
- static rowSelection($anchorCell, $headCell = $anchorCell) {
26315
- const table = $anchorCell.node(-1);
26316
- const map = TableMap.get(table);
26317
- const tableStart = $anchorCell.start(-1);
26318
- const anchorRect = map.findCell($anchorCell.pos - tableStart);
26319
- const headRect = map.findCell($headCell.pos - tableStart);
26320
- const doc = $anchorCell.node(0);
26321
- if (anchorRect.left <= headRect.left) {
26322
- if (anchorRect.left > 0)
26323
- $anchorCell = doc.resolve(
26324
- tableStart + map.map[anchorRect.top * map.width]
26325
- );
26326
- if (headRect.right < map.width)
26327
- $headCell = doc.resolve(
26328
- tableStart + map.map[map.width * (headRect.top + 1) - 1]
26329
- );
26330
- } else {
26331
- if (headRect.left > 0)
26332
- $headCell = doc.resolve(tableStart + map.map[headRect.top * map.width]);
26333
- if (anchorRect.right < map.width)
26334
- $anchorCell = doc.resolve(
26335
- tableStart + map.map[map.width * (anchorRect.top + 1) - 1]
26336
- );
26337
- }
26338
- return new _CellSelection($anchorCell, $headCell);
26339
- }
26340
- toJSON() {
26341
- return {
26342
- type: "cell",
26343
- anchor: this.$anchorCell.pos,
26344
- head: this.$headCell.pos
26345
- };
26346
- }
26347
- static fromJSON(doc, json) {
26348
- return new _CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
26349
- }
26350
- static create(doc, anchorCell, headCell = anchorCell) {
26351
- return new _CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
26352
- }
26353
- getBookmark() {
26354
- return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
26355
- }
26429
+ const result = {
26430
+ ...attrs,
26431
+ colspan: attrs.colspan - n
26432
+ };
26433
+ if (result.colwidth) {
26434
+ result.colwidth = result.colwidth.slice();
26435
+ result.colwidth.splice(pos, n);
26436
+ if (!result.colwidth.some((w) => w > 0)) result.colwidth = null;
26437
+ }
26438
+ return result;
26439
+ }
26440
+
26441
+ //#endregion
26442
+ //#region src/cellselection.ts
26443
+ /**
26444
+ * A [`Selection`](http://prosemirror.net/docs/ref/#state.Selection)
26445
+ * subclass that represents a cell selection spanning part of a table.
26446
+ * With the plugin enabled, these will be created when the user
26447
+ * selects across cells, and will be drawn by giving selected cells a
26448
+ * `selectedCell` CSS class.
26449
+ *
26450
+ * @public
26451
+ */
26452
+ var CellSelection = class CellSelection extends Selection {
26453
+ constructor($anchorCell, $headCell = $anchorCell) {
26454
+ const table = $anchorCell.node(-1);
26455
+ const map = TableMap.get(table);
26456
+ const tableStart = $anchorCell.start(-1);
26457
+ const rect = map.rectBetween($anchorCell.pos - tableStart, $headCell.pos - tableStart);
26458
+ const doc = $anchorCell.node(0);
26459
+ const cells = map.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart);
26460
+ cells.unshift($headCell.pos - tableStart);
26461
+ const ranges = cells.map((pos) => {
26462
+ const cell = table.nodeAt(pos);
26463
+ if (!cell) throw new RangeError(`No cell with offset ${pos} found`);
26464
+ const from = tableStart + pos + 1;
26465
+ return new SelectionRange(doc.resolve(from), doc.resolve(from + cell.content.size));
26466
+ });
26467
+ super(ranges[0].$from, ranges[0].$to, ranges);
26468
+ this.$anchorCell = $anchorCell;
26469
+ this.$headCell = $headCell;
26470
+ }
26471
+ map(doc, mapping) {
26472
+ const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
26473
+ const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
26474
+ if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
26475
+ const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1);
26476
+ if (tableChanged && this.isRowSelection()) return CellSelection.rowSelection($anchorCell, $headCell);
26477
+ else if (tableChanged && this.isColSelection()) return CellSelection.colSelection($anchorCell, $headCell);
26478
+ else return new CellSelection($anchorCell, $headCell);
26479
+ }
26480
+ return TextSelection.between($anchorCell, $headCell);
26481
+ }
26482
+ content() {
26483
+ const table = this.$anchorCell.node(-1);
26484
+ const map = TableMap.get(table);
26485
+ const tableStart = this.$anchorCell.start(-1);
26486
+ const rect = map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart);
26487
+ const seen = {};
26488
+ const rows = [];
26489
+ for (let row = rect.top; row < rect.bottom; row++) {
26490
+ const rowContent = [];
26491
+ for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
26492
+ const pos = map.map[index];
26493
+ if (seen[pos]) continue;
26494
+ seen[pos] = true;
26495
+ const cellRect = map.findCell(pos);
26496
+ let cell = table.nodeAt(pos);
26497
+ if (!cell) throw new RangeError(`No cell with offset ${pos} found`);
26498
+ const extraLeft = rect.left - cellRect.left;
26499
+ const extraRight = cellRect.right - rect.right;
26500
+ if (extraLeft > 0 || extraRight > 0) {
26501
+ let attrs = cell.attrs;
26502
+ if (extraLeft > 0) attrs = removeColSpan(attrs, 0, extraLeft);
26503
+ if (extraRight > 0) attrs = removeColSpan(attrs, attrs.colspan - extraRight, extraRight);
26504
+ if (cellRect.left < rect.left) {
26505
+ cell = cell.type.createAndFill(attrs);
26506
+ if (!cell) throw new RangeError(`Could not create cell with attrs ${JSON.stringify(attrs)}`);
26507
+ } else cell = cell.type.create(attrs, cell.content);
26508
+ }
26509
+ if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
26510
+ const attrs = {
26511
+ ...cell.attrs,
26512
+ rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
26513
+ };
26514
+ if (cellRect.top < rect.top) cell = cell.type.createAndFill(attrs);
26515
+ else cell = cell.type.create(attrs, cell.content);
26516
+ }
26517
+ rowContent.push(cell);
26518
+ }
26519
+ rows.push(table.child(row).copy(Fragment.from(rowContent)));
26520
+ }
26521
+ const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
26522
+ return new Slice(Fragment.from(fragment), 1, 1);
26523
+ }
26524
+ replace(tr, content = Slice.empty) {
26525
+ const mapFrom = tr.steps.length, ranges = this.ranges;
26526
+ for (let i = 0; i < ranges.length; i++) {
26527
+ const { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
26528
+ tr.replace(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
26529
+ }
26530
+ const sel = Selection.findFrom(tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)), -1);
26531
+ if (sel) tr.setSelection(sel);
26532
+ }
26533
+ replaceWith(tr, node) {
26534
+ this.replace(tr, new Slice(Fragment.from(node), 0, 0));
26535
+ }
26536
+ forEachCell(f) {
26537
+ const table = this.$anchorCell.node(-1);
26538
+ const map = TableMap.get(table);
26539
+ const tableStart = this.$anchorCell.start(-1);
26540
+ const cells = map.cellsInRect(map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart));
26541
+ for (let i = 0; i < cells.length; i++) f(table.nodeAt(cells[i]), tableStart + cells[i]);
26542
+ }
26543
+ isColSelection() {
26544
+ const anchorTop = this.$anchorCell.index(-1);
26545
+ const headTop = this.$headCell.index(-1);
26546
+ if (Math.min(anchorTop, headTop) > 0) return false;
26547
+ const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
26548
+ const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan;
26549
+ return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount;
26550
+ }
26551
+ static colSelection($anchorCell, $headCell = $anchorCell) {
26552
+ const table = $anchorCell.node(-1);
26553
+ const map = TableMap.get(table);
26554
+ const tableStart = $anchorCell.start(-1);
26555
+ const anchorRect = map.findCell($anchorCell.pos - tableStart);
26556
+ const headRect = map.findCell($headCell.pos - tableStart);
26557
+ const doc = $anchorCell.node(0);
26558
+ if (anchorRect.top <= headRect.top) {
26559
+ if (anchorRect.top > 0) $anchorCell = doc.resolve(tableStart + map.map[anchorRect.left]);
26560
+ if (headRect.bottom < map.height) $headCell = doc.resolve(tableStart + map.map[map.width * (map.height - 1) + headRect.right - 1]);
26561
+ } else {
26562
+ if (headRect.top > 0) $headCell = doc.resolve(tableStart + map.map[headRect.left]);
26563
+ if (anchorRect.bottom < map.height) $anchorCell = doc.resolve(tableStart + map.map[map.width * (map.height - 1) + anchorRect.right - 1]);
26564
+ }
26565
+ return new CellSelection($anchorCell, $headCell);
26566
+ }
26567
+ isRowSelection() {
26568
+ const table = this.$anchorCell.node(-1);
26569
+ const map = TableMap.get(table);
26570
+ const tableStart = this.$anchorCell.start(-1);
26571
+ const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
26572
+ const headLeft = map.colCount(this.$headCell.pos - tableStart);
26573
+ if (Math.min(anchorLeft, headLeft) > 0) return false;
26574
+ const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
26575
+ const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
26576
+ return Math.max(anchorRight, headRight) == map.width;
26577
+ }
26578
+ eq(other) {
26579
+ return other instanceof CellSelection && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos;
26580
+ }
26581
+ static rowSelection($anchorCell, $headCell = $anchorCell) {
26582
+ const table = $anchorCell.node(-1);
26583
+ const map = TableMap.get(table);
26584
+ const tableStart = $anchorCell.start(-1);
26585
+ const anchorRect = map.findCell($anchorCell.pos - tableStart);
26586
+ const headRect = map.findCell($headCell.pos - tableStart);
26587
+ const doc = $anchorCell.node(0);
26588
+ if (anchorRect.left <= headRect.left) {
26589
+ if (anchorRect.left > 0) $anchorCell = doc.resolve(tableStart + map.map[anchorRect.top * map.width]);
26590
+ if (headRect.right < map.width) $headCell = doc.resolve(tableStart + map.map[map.width * (headRect.top + 1) - 1]);
26591
+ } else {
26592
+ if (headRect.left > 0) $headCell = doc.resolve(tableStart + map.map[headRect.top * map.width]);
26593
+ if (anchorRect.right < map.width) $anchorCell = doc.resolve(tableStart + map.map[map.width * (anchorRect.top + 1) - 1]);
26594
+ }
26595
+ return new CellSelection($anchorCell, $headCell);
26596
+ }
26597
+ toJSON() {
26598
+ return {
26599
+ type: "cell",
26600
+ anchor: this.$anchorCell.pos,
26601
+ head: this.$headCell.pos
26602
+ };
26603
+ }
26604
+ static fromJSON(doc, json) {
26605
+ return new CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
26606
+ }
26607
+ static create(doc, anchorCell, headCell = anchorCell) {
26608
+ return new CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
26609
+ }
26610
+ getBookmark() {
26611
+ return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
26612
+ }
26356
26613
  };
26357
26614
  CellSelection.prototype.visible = false;
26358
26615
  Selection.jsonID("cell", CellSelection);
26359
- var CellBookmark = class _CellBookmark {
26360
- constructor(anchor, head) {
26361
- this.anchor = anchor;
26362
- this.head = head;
26363
- }
26364
- map(mapping) {
26365
- return new _CellBookmark(mapping.map(this.anchor), mapping.map(this.head));
26366
- }
26367
- resolve(doc) {
26368
- const $anchorCell = doc.resolve(this.anchor), $headCell = doc.resolve(this.head);
26369
- if ($anchorCell.parent.type.spec.tableRole == "row" && $headCell.parent.type.spec.tableRole == "row" && $anchorCell.index() < $anchorCell.parent.childCount && $headCell.index() < $headCell.parent.childCount && inSameTable($anchorCell, $headCell))
26370
- return new CellSelection($anchorCell, $headCell);
26371
- else return Selection.near($headCell, 1);
26372
- }
26616
+ /**
26617
+ * @public
26618
+ */
26619
+ var CellBookmark = class CellBookmark {
26620
+ constructor(anchor, head) {
26621
+ this.anchor = anchor;
26622
+ this.head = head;
26623
+ }
26624
+ map(mapping) {
26625
+ return new CellBookmark(mapping.map(this.anchor), mapping.map(this.head));
26626
+ }
26627
+ resolve(doc) {
26628
+ const $anchorCell = doc.resolve(this.anchor), $headCell = doc.resolve(this.head);
26629
+ if ($anchorCell.parent.type.spec.tableRole == "row" && $headCell.parent.type.spec.tableRole == "row" && $anchorCell.index() < $anchorCell.parent.childCount && $headCell.index() < $headCell.parent.childCount && inSameTable($anchorCell, $headCell)) return new CellSelection($anchorCell, $headCell);
26630
+ else return Selection.near($headCell, 1);
26631
+ }
26373
26632
  };
26374
26633
  function drawCellSelection(state) {
26375
- if (!(state.selection instanceof CellSelection)) return null;
26376
- const cells = [];
26377
- state.selection.forEachCell((node, pos) => {
26378
- cells.push(
26379
- Decoration.node(pos, pos + node.nodeSize, { class: "selectedCell" })
26380
- );
26381
- });
26382
- return DecorationSet.create(state.doc, cells);
26634
+ if (!(state.selection instanceof CellSelection)) return null;
26635
+ const cells = [];
26636
+ state.selection.forEachCell((node, pos) => {
26637
+ cells.push(Decoration.node(pos, pos + node.nodeSize, { class: "selectedCell" }));
26638
+ });
26639
+ return DecorationSet.create(state.doc, cells);
26383
26640
  }
26384
26641
  function isCellBoundarySelection({ $from, $to }) {
26385
- if ($from.pos == $to.pos || $from.pos < $to.pos - 6) return false;
26386
- let afterFrom = $from.pos;
26387
- let beforeTo = $to.pos;
26388
- let depth = $from.depth;
26389
- for (; depth >= 0; depth--, afterFrom++)
26390
- if ($from.after(depth + 1) < $from.end(depth)) break;
26391
- for (let d = $to.depth; d >= 0; d--, beforeTo--)
26392
- if ($to.before(d + 1) > $to.start(d)) break;
26393
- return afterFrom == beforeTo && /row|table/.test($from.node(depth).type.spec.tableRole);
26642
+ if ($from.pos == $to.pos || $from.pos < $to.pos - 6) return false;
26643
+ let afterFrom = $from.pos;
26644
+ let beforeTo = $to.pos;
26645
+ let depth = $from.depth;
26646
+ for (; depth >= 0; depth--, afterFrom++) if ($from.after(depth + 1) < $from.end(depth)) break;
26647
+ for (let d = $to.depth; d >= 0; d--, beforeTo--) if ($to.before(d + 1) > $to.start(d)) break;
26648
+ return afterFrom == beforeTo && /row|table/.test($from.node(depth).type.spec.tableRole);
26394
26649
  }
26395
26650
  function isTextSelectionAcrossCells({ $from, $to }) {
26396
- let fromCellBoundaryNode;
26397
- let toCellBoundaryNode;
26398
- for (let i = $from.depth; i > 0; i--) {
26399
- const node = $from.node(i);
26400
- if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
26401
- fromCellBoundaryNode = node;
26402
- break;
26403
- }
26404
- }
26405
- for (let i = $to.depth; i > 0; i--) {
26406
- const node = $to.node(i);
26407
- if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
26408
- toCellBoundaryNode = node;
26409
- break;
26410
- }
26411
- }
26412
- return fromCellBoundaryNode !== toCellBoundaryNode && $to.parentOffset === 0;
26651
+ let fromCellBoundaryNode;
26652
+ let toCellBoundaryNode;
26653
+ for (let i = $from.depth; i > 0; i--) {
26654
+ const node = $from.node(i);
26655
+ if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
26656
+ fromCellBoundaryNode = node;
26657
+ break;
26658
+ }
26659
+ }
26660
+ for (let i = $to.depth; i > 0; i--) {
26661
+ const node = $to.node(i);
26662
+ if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
26663
+ toCellBoundaryNode = node;
26664
+ break;
26665
+ }
26666
+ }
26667
+ return fromCellBoundaryNode !== toCellBoundaryNode && $to.parentOffset === 0;
26413
26668
  }
26414
26669
  function normalizeSelection(state, tr, allowTableNodeSelection) {
26415
- const sel = (tr || state).selection;
26416
- const doc = (tr || state).doc;
26417
- let normalize;
26418
- let role;
26419
- if (sel instanceof NodeSelection && (role = sel.node.type.spec.tableRole)) {
26420
- if (role == "cell" || role == "header_cell") {
26421
- normalize = CellSelection.create(doc, sel.from);
26422
- } else if (role == "row") {
26423
- const $cell = doc.resolve(sel.from + 1);
26424
- normalize = CellSelection.rowSelection($cell, $cell);
26425
- } else if (!allowTableNodeSelection) {
26426
- const map = TableMap.get(sel.node);
26427
- const start = sel.from + 1;
26428
- const lastCell = start + map.map[map.width * map.height - 1];
26429
- normalize = CellSelection.create(doc, start + 1, lastCell);
26430
- }
26431
- } else if (sel instanceof TextSelection && isCellBoundarySelection(sel)) {
26432
- normalize = TextSelection.create(doc, sel.from);
26433
- } else if (sel instanceof TextSelection && isTextSelectionAcrossCells(sel)) {
26434
- normalize = TextSelection.create(doc, sel.$from.start(), sel.$from.end());
26435
- }
26436
- if (normalize) (tr || (tr = state.tr)).setSelection(normalize);
26437
- return tr;
26670
+ const sel = (tr || state).selection;
26671
+ const doc = (tr || state).doc;
26672
+ let normalize;
26673
+ let role;
26674
+ if (sel instanceof NodeSelection && (role = sel.node.type.spec.tableRole)) {
26675
+ if (role == "cell" || role == "header_cell") normalize = CellSelection.create(doc, sel.from);
26676
+ else if (role == "row") {
26677
+ const $cell = doc.resolve(sel.from + 1);
26678
+ normalize = CellSelection.rowSelection($cell, $cell);
26679
+ } else if (!allowTableNodeSelection) {
26680
+ const map = TableMap.get(sel.node);
26681
+ const start = sel.from + 1;
26682
+ const lastCell = start + map.map[map.width * map.height - 1];
26683
+ normalize = CellSelection.create(doc, start + 1, lastCell);
26684
+ }
26685
+ } else if (sel instanceof TextSelection && isCellBoundarySelection(sel)) normalize = TextSelection.create(doc, sel.from);
26686
+ else if (sel instanceof TextSelection && isTextSelectionAcrossCells(sel)) normalize = TextSelection.create(doc, sel.$from.start(), sel.$from.end());
26687
+ if (normalize) (tr || (tr = state.tr)).setSelection(normalize);
26688
+ return tr;
26438
26689
  }
26439
- var fixTablesKey = new PluginKey("fix-tables");
26690
+
26691
+ //#endregion
26692
+ //#region src/fixtables.ts
26693
+ /**
26694
+ * @public
26695
+ */
26696
+ const fixTablesKey = new PluginKey("fix-tables");
26697
+ /**
26698
+ * Helper for iterating through the nodes in a document that changed
26699
+ * compared to the given previous document. Useful for avoiding
26700
+ * duplicate work on each transaction.
26701
+ *
26702
+ * @public
26703
+ */
26440
26704
  function changedDescendants(old, cur, offset, f) {
26441
- const oldSize = old.childCount, curSize = cur.childCount;
26442
- outer: for (let i = 0, j = 0; i < curSize; i++) {
26443
- const child = cur.child(i);
26444
- for (let scan = j, e = Math.min(oldSize, i + 3); scan < e; scan++) {
26445
- if (old.child(scan) == child) {
26446
- j = scan + 1;
26447
- offset += child.nodeSize;
26448
- continue outer;
26449
- }
26450
- }
26451
- f(child, offset);
26452
- if (j < oldSize && old.child(j).sameMarkup(child))
26453
- changedDescendants(old.child(j), child, offset + 1, f);
26454
- else child.nodesBetween(0, child.content.size, f, offset + 1);
26455
- offset += child.nodeSize;
26456
- }
26705
+ const oldSize = old.childCount, curSize = cur.childCount;
26706
+ outer: for (let i = 0, j = 0; i < curSize; i++) {
26707
+ const child = cur.child(i);
26708
+ for (let scan = j, e = Math.min(oldSize, i + 3); scan < e; scan++) if (old.child(scan) == child) {
26709
+ j = scan + 1;
26710
+ offset += child.nodeSize;
26711
+ continue outer;
26712
+ }
26713
+ f(child, offset);
26714
+ if (j < oldSize && old.child(j).sameMarkup(child)) changedDescendants(old.child(j), child, offset + 1, f);
26715
+ else child.nodesBetween(0, child.content.size, f, offset + 1);
26716
+ offset += child.nodeSize;
26717
+ }
26457
26718
  }
26719
+ /**
26720
+ * Inspect all tables in the given state's document and return a
26721
+ * transaction that fixes them, if necessary. If `oldState` was
26722
+ * provided, that is assumed to hold a previous, known-good state,
26723
+ * which will be used to avoid re-scanning unchanged parts of the
26724
+ * document.
26725
+ *
26726
+ * @public
26727
+ */
26458
26728
  function fixTables(state, oldState) {
26459
- let tr;
26460
- const check = (node, pos) => {
26461
- if (node.type.spec.tableRole == "table")
26462
- tr = fixTable(state, node, pos, tr);
26463
- };
26464
- if (!oldState) state.doc.descendants(check);
26465
- else if (oldState.doc != state.doc)
26466
- changedDescendants(oldState.doc, state.doc, 0, check);
26467
- return tr;
26729
+ let tr;
26730
+ const check = (node, pos) => {
26731
+ if (node.type.spec.tableRole == "table") tr = fixTable(state, node, pos, tr);
26732
+ };
26733
+ if (!oldState) state.doc.descendants(check);
26734
+ else if (oldState.doc != state.doc) changedDescendants(oldState.doc, state.doc, 0, check);
26735
+ return tr;
26468
26736
  }
26469
26737
  function fixTable(state, table, tablePos, tr) {
26470
- const map = TableMap.get(table);
26471
- if (!map.problems) return tr;
26472
- if (!tr) tr = state.tr;
26473
- const mustAdd = [];
26474
- for (let i = 0; i < map.height; i++) mustAdd.push(0);
26475
- for (let i = 0; i < map.problems.length; i++) {
26476
- const prob = map.problems[i];
26477
- if (prob.type == "collision") {
26478
- const cell = table.nodeAt(prob.pos);
26479
- if (!cell) continue;
26480
- const attrs = cell.attrs;
26481
- for (let j = 0; j < attrs.rowspan; j++) mustAdd[prob.row + j] += prob.n;
26482
- tr.setNodeMarkup(
26483
- tr.mapping.map(tablePos + 1 + prob.pos),
26484
- null,
26485
- removeColSpan(attrs, attrs.colspan - prob.n, prob.n)
26486
- );
26487
- } else if (prob.type == "missing") {
26488
- mustAdd[prob.row] += prob.n;
26489
- } else if (prob.type == "overlong_rowspan") {
26490
- const cell = table.nodeAt(prob.pos);
26491
- if (!cell) continue;
26492
- tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
26493
- ...cell.attrs,
26494
- rowspan: cell.attrs.rowspan - prob.n
26495
- });
26496
- } else if (prob.type == "colwidth mismatch") {
26497
- const cell = table.nodeAt(prob.pos);
26498
- if (!cell) continue;
26499
- tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
26500
- ...cell.attrs,
26501
- colwidth: prob.colwidth
26502
- });
26503
- } else if (prob.type == "zero_sized") {
26504
- const pos = tr.mapping.map(tablePos);
26505
- tr.delete(pos, pos + table.nodeSize);
26506
- }
26507
- }
26508
- let first, last;
26509
- for (let i = 0; i < mustAdd.length; i++)
26510
- if (mustAdd[i]) {
26511
- if (first == null) first = i;
26512
- last = i;
26513
- }
26514
- for (let i = 0, pos = tablePos + 1; i < map.height; i++) {
26515
- const row = table.child(i);
26516
- const end = pos + row.nodeSize;
26517
- const add = mustAdd[i];
26518
- if (add > 0) {
26519
- let role = "cell";
26520
- if (row.firstChild) {
26521
- role = row.firstChild.type.spec.tableRole;
26522
- }
26523
- const nodes = [];
26524
- for (let j = 0; j < add; j++) {
26525
- const node = tableNodeTypes(state.schema)[role].createAndFill();
26526
- if (node) nodes.push(node);
26527
- }
26528
- const side = (i == 0 || first == i - 1) && last == i ? pos + 1 : end - 1;
26529
- tr.insert(tr.mapping.map(side), nodes);
26530
- }
26531
- pos = end;
26532
- }
26533
- return tr.setMeta(fixTablesKey, { fixTables: true });
26738
+ const map = TableMap.get(table);
26739
+ if (!map.problems) return tr;
26740
+ if (!tr) tr = state.tr;
26741
+ const mustAdd = [];
26742
+ for (let i = 0; i < map.height; i++) mustAdd.push(0);
26743
+ for (let i = 0; i < map.problems.length; i++) {
26744
+ const prob = map.problems[i];
26745
+ if (prob.type == "collision") {
26746
+ const cell = table.nodeAt(prob.pos);
26747
+ if (!cell) continue;
26748
+ const attrs = cell.attrs;
26749
+ for (let j = 0; j < attrs.rowspan; j++) mustAdd[prob.row + j] += prob.n;
26750
+ tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, removeColSpan(attrs, attrs.colspan - prob.n, prob.n));
26751
+ } else if (prob.type == "missing") mustAdd[prob.row] += prob.n;
26752
+ else if (prob.type == "overlong_rowspan") {
26753
+ const cell = table.nodeAt(prob.pos);
26754
+ if (!cell) continue;
26755
+ tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
26756
+ ...cell.attrs,
26757
+ rowspan: cell.attrs.rowspan - prob.n
26758
+ });
26759
+ } else if (prob.type == "colwidth mismatch") {
26760
+ const cell = table.nodeAt(prob.pos);
26761
+ if (!cell) continue;
26762
+ tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
26763
+ ...cell.attrs,
26764
+ colwidth: prob.colwidth
26765
+ });
26766
+ } else if (prob.type == "zero_sized") {
26767
+ const pos = tr.mapping.map(tablePos);
26768
+ tr.delete(pos, pos + table.nodeSize);
26769
+ }
26770
+ }
26771
+ let first, last;
26772
+ for (let i = 0; i < mustAdd.length; i++) if (mustAdd[i]) {
26773
+ if (first == null) first = i;
26774
+ last = i;
26775
+ }
26776
+ for (let i = 0, pos = tablePos + 1; i < map.height; i++) {
26777
+ const row = table.child(i);
26778
+ const end = pos + row.nodeSize;
26779
+ const add = mustAdd[i];
26780
+ if (add > 0) {
26781
+ let role = "cell";
26782
+ if (row.firstChild) role = row.firstChild.type.spec.tableRole;
26783
+ const nodes = [];
26784
+ for (let j = 0; j < add; j++) {
26785
+ const node = tableNodeTypes(state.schema)[role].createAndFill();
26786
+ if (node) nodes.push(node);
26787
+ }
26788
+ const side = (i == 0 || first == i - 1) && last == i ? pos + 1 : end - 1;
26789
+ tr.insert(tr.mapping.map(side), nodes);
26790
+ }
26791
+ pos = end;
26792
+ }
26793
+ return tr.setMeta(fixTablesKey, { fixTables: true });
26534
26794
  }
26795
+ /**
26796
+ * Deletes the content of the selected cells, if they are not empty.
26797
+ *
26798
+ * @public
26799
+ */
26535
26800
  function deleteCellSelection(state, dispatch) {
26536
- const sel = state.selection;
26537
- if (!(sel instanceof CellSelection)) return false;
26538
- if (dispatch) {
26539
- const tr = state.tr;
26540
- const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content;
26541
- sel.forEachCell((cell, pos) => {
26542
- if (!cell.content.eq(baseContent))
26543
- tr.replace(
26544
- tr.mapping.map(pos + 1),
26545
- tr.mapping.map(pos + cell.nodeSize - 1),
26546
- new Slice(baseContent, 0, 0)
26547
- );
26548
- });
26549
- if (tr.docChanged) dispatch(tr);
26550
- }
26551
- return true;
26801
+ const sel = state.selection;
26802
+ if (!(sel instanceof CellSelection)) return false;
26803
+ if (dispatch) {
26804
+ const tr = state.tr;
26805
+ const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content;
26806
+ sel.forEachCell((cell, pos) => {
26807
+ if (!cell.content.eq(baseContent)) tr.replace(tr.mapping.map(pos + 1), tr.mapping.map(pos + cell.nodeSize - 1), new Slice(baseContent, 0, 0));
26808
+ });
26809
+ if (tr.docChanged) dispatch(tr);
26810
+ }
26811
+ return true;
26552
26812
  }
26813
+
26814
+ //#endregion
26815
+ //#region src/copypaste.ts
26816
+ /**
26817
+ * Get a rectangular area of cells from a slice, or null if the outer
26818
+ * nodes of the slice aren't table cells or rows.
26819
+ *
26820
+ * @internal
26821
+ */
26553
26822
  function pastedCells(slice) {
26554
- if (!slice.size) return null;
26555
- let { content, openStart, openEnd } = slice;
26556
- while (content.childCount == 1 && (openStart > 0 && openEnd > 0 || content.child(0).type.spec.tableRole == "table")) {
26557
- openStart--;
26558
- openEnd--;
26559
- content = content.child(0).content;
26560
- }
26561
- const first = content.child(0);
26562
- const role = first.type.spec.tableRole;
26563
- const schema = first.type.schema, rows = [];
26564
- if (role == "row") {
26565
- for (let i = 0; i < content.childCount; i++) {
26566
- let cells = content.child(i).content;
26567
- const left = i ? 0 : Math.max(0, openStart - 1);
26568
- const right = i < content.childCount - 1 ? 0 : Math.max(0, openEnd - 1);
26569
- if (left || right)
26570
- cells = fitSlice(
26571
- tableNodeTypes(schema).row,
26572
- new Slice(cells, left, right)
26573
- ).content;
26574
- rows.push(cells);
26575
- }
26576
- } else if (role == "cell" || role == "header_cell") {
26577
- rows.push(
26578
- openStart || openEnd ? fitSlice(
26579
- tableNodeTypes(schema).row,
26580
- new Slice(content, openStart, openEnd)
26581
- ).content : content
26582
- );
26583
- } else {
26584
- return null;
26585
- }
26586
- return ensureRectangular(schema, rows);
26823
+ if (slice.size === 0) return null;
26824
+ let { content, openStart, openEnd } = slice;
26825
+ while (content.childCount == 1 && (openStart > 0 && openEnd > 0 || content.child(0).type.spec.tableRole == "table")) {
26826
+ openStart--;
26827
+ openEnd--;
26828
+ content = content.child(0).content;
26829
+ }
26830
+ const first = content.child(0);
26831
+ const role = first.type.spec.tableRole;
26832
+ const schema = first.type.schema, rows = [];
26833
+ if (role == "row") for (let i = 0; i < content.childCount; i++) {
26834
+ let cells = content.child(i).content;
26835
+ const left = i ? 0 : Math.max(0, openStart - 1);
26836
+ const right = i < content.childCount - 1 ? 0 : Math.max(0, openEnd - 1);
26837
+ if (left || right) cells = fitSlice(tableNodeTypes(schema).row, new Slice(cells, left, right)).content;
26838
+ rows.push(cells);
26839
+ }
26840
+ else if (role == "cell" || role == "header_cell") rows.push(openStart || openEnd ? fitSlice(tableNodeTypes(schema).row, new Slice(content, openStart, openEnd)).content : content);
26841
+ else return null;
26842
+ return ensureRectangular(schema, rows);
26587
26843
  }
26588
26844
  function ensureRectangular(schema, rows) {
26589
- const widths = [];
26590
- for (let i = 0; i < rows.length; i++) {
26591
- const row = rows[i];
26592
- for (let j = row.childCount - 1; j >= 0; j--) {
26593
- const { rowspan, colspan } = row.child(j).attrs;
26594
- for (let r = i; r < i + rowspan; r++)
26595
- widths[r] = (widths[r] || 0) + colspan;
26596
- }
26597
- }
26598
- let width = 0;
26599
- for (let r = 0; r < widths.length; r++) width = Math.max(width, widths[r]);
26600
- for (let r = 0; r < widths.length; r++) {
26601
- if (r >= rows.length) rows.push(Fragment.empty);
26602
- if (widths[r] < width) {
26603
- const empty = tableNodeTypes(schema).cell.createAndFill();
26604
- const cells = [];
26605
- for (let i = widths[r]; i < width; i++) {
26606
- cells.push(empty);
26607
- }
26608
- rows[r] = rows[r].append(Fragment.from(cells));
26609
- }
26610
- }
26611
- return { height: rows.length, width, rows };
26845
+ const widths = [];
26846
+ for (let i = 0; i < rows.length; i++) {
26847
+ const row = rows[i];
26848
+ for (let j = row.childCount - 1; j >= 0; j--) {
26849
+ const { rowspan, colspan } = row.child(j).attrs;
26850
+ for (let r = i; r < i + rowspan; r++) widths[r] = (widths[r] || 0) + colspan;
26851
+ }
26852
+ }
26853
+ let width = 0;
26854
+ for (let r = 0; r < widths.length; r++) width = Math.max(width, widths[r]);
26855
+ for (let r = 0; r < widths.length; r++) {
26856
+ if (r >= rows.length) rows.push(Fragment.empty);
26857
+ if (widths[r] < width) {
26858
+ const empty = tableNodeTypes(schema).cell.createAndFill();
26859
+ const cells = [];
26860
+ for (let i = widths[r]; i < width; i++) cells.push(empty);
26861
+ rows[r] = rows[r].append(Fragment.from(cells));
26862
+ }
26863
+ }
26864
+ return {
26865
+ height: rows.length,
26866
+ width,
26867
+ rows
26868
+ };
26612
26869
  }
26613
26870
  function fitSlice(nodeType, slice) {
26614
- const node = nodeType.createAndFill();
26615
- const tr = new Transform(node).replace(0, node.content.size, slice);
26616
- return tr.doc;
26871
+ const node = nodeType.createAndFill();
26872
+ return new Transform(node).replace(0, node.content.size, slice).doc;
26617
26873
  }
26874
+ /**
26875
+ * Clip or extend (repeat) the given set of cells to cover the given
26876
+ * width and height. Will clip rowspan/colspan cells at the edges when
26877
+ * they stick out.
26878
+ *
26879
+ * @internal
26880
+ */
26618
26881
  function clipCells({ width, height, rows }, newWidth, newHeight) {
26619
- if (width != newWidth) {
26620
- const added = [];
26621
- const newRows = [];
26622
- for (let row = 0; row < rows.length; row++) {
26623
- const frag = rows[row], cells = [];
26624
- for (let col = added[row] || 0, i = 0; col < newWidth; i++) {
26625
- let cell = frag.child(i % frag.childCount);
26626
- if (col + cell.attrs.colspan > newWidth)
26627
- cell = cell.type.createChecked(
26628
- removeColSpan(
26629
- cell.attrs,
26630
- cell.attrs.colspan,
26631
- col + cell.attrs.colspan - newWidth
26632
- ),
26633
- cell.content
26634
- );
26635
- cells.push(cell);
26636
- col += cell.attrs.colspan;
26637
- for (let j = 1; j < cell.attrs.rowspan; j++)
26638
- added[row + j] = (added[row + j] || 0) + cell.attrs.colspan;
26639
- }
26640
- newRows.push(Fragment.from(cells));
26641
- }
26642
- rows = newRows;
26643
- width = newWidth;
26644
- }
26645
- if (height != newHeight) {
26646
- const newRows = [];
26647
- for (let row = 0, i = 0; row < newHeight; row++, i++) {
26648
- const cells = [], source = rows[i % height];
26649
- for (let j = 0; j < source.childCount; j++) {
26650
- let cell = source.child(j);
26651
- if (row + cell.attrs.rowspan > newHeight)
26652
- cell = cell.type.create(
26653
- {
26654
- ...cell.attrs,
26655
- rowspan: Math.max(1, newHeight - cell.attrs.rowspan)
26656
- },
26657
- cell.content
26658
- );
26659
- cells.push(cell);
26660
- }
26661
- newRows.push(Fragment.from(cells));
26662
- }
26663
- rows = newRows;
26664
- height = newHeight;
26665
- }
26666
- return { width, height, rows };
26882
+ if (width != newWidth) {
26883
+ const added = [];
26884
+ const newRows = [];
26885
+ for (let row = 0; row < rows.length; row++) {
26886
+ const frag = rows[row], cells = [];
26887
+ for (let col = added[row] || 0, i = 0; col < newWidth; i++) {
26888
+ let cell = frag.child(i % frag.childCount);
26889
+ if (col + cell.attrs.colspan > newWidth) cell = cell.type.createChecked(removeColSpan(cell.attrs, cell.attrs.colspan, col + cell.attrs.colspan - newWidth), cell.content);
26890
+ cells.push(cell);
26891
+ col += cell.attrs.colspan;
26892
+ for (let j = 1; j < cell.attrs.rowspan; j++) added[row + j] = (added[row + j] || 0) + cell.attrs.colspan;
26893
+ }
26894
+ newRows.push(Fragment.from(cells));
26895
+ }
26896
+ rows = newRows;
26897
+ width = newWidth;
26898
+ }
26899
+ if (height != newHeight) {
26900
+ const newRows = [];
26901
+ for (let row = 0, i = 0; row < newHeight; row++, i++) {
26902
+ const cells = [], source = rows[i % height];
26903
+ for (let j = 0; j < source.childCount; j++) {
26904
+ let cell = source.child(j);
26905
+ if (row + cell.attrs.rowspan > newHeight) cell = cell.type.create({
26906
+ ...cell.attrs,
26907
+ rowspan: Math.max(1, newHeight - cell.attrs.rowspan)
26908
+ }, cell.content);
26909
+ cells.push(cell);
26910
+ }
26911
+ newRows.push(Fragment.from(cells));
26912
+ }
26913
+ rows = newRows;
26914
+ height = newHeight;
26915
+ }
26916
+ return {
26917
+ width,
26918
+ height,
26919
+ rows
26920
+ };
26667
26921
  }
26668
26922
  function growTable(tr, map, table, start, width, height, mapFrom) {
26669
- const schema = tr.doc.type.schema;
26670
- const types = tableNodeTypes(schema);
26671
- let empty;
26672
- let emptyHead;
26673
- if (width > map.width) {
26674
- for (let row = 0, rowEnd = 0; row < map.height; row++) {
26675
- const rowNode = table.child(row);
26676
- rowEnd += rowNode.nodeSize;
26677
- const cells = [];
26678
- let add;
26679
- if (rowNode.lastChild == null || rowNode.lastChild.type == types.cell)
26680
- add = empty || (empty = types.cell.createAndFill());
26681
- else add = emptyHead || (emptyHead = types.header_cell.createAndFill());
26682
- for (let i = map.width; i < width; i++) cells.push(add);
26683
- tr.insert(tr.mapping.slice(mapFrom).map(rowEnd - 1 + start), cells);
26684
- }
26685
- }
26686
- if (height > map.height) {
26687
- const cells = [];
26688
- for (let i = 0, start2 = (map.height - 1) * map.width; i < Math.max(map.width, width); i++) {
26689
- const header = i >= map.width ? false : table.nodeAt(map.map[start2 + i]).type == types.header_cell;
26690
- cells.push(
26691
- header ? emptyHead || (emptyHead = types.header_cell.createAndFill()) : empty || (empty = types.cell.createAndFill())
26692
- );
26693
- }
26694
- const emptyRow = types.row.create(null, Fragment.from(cells)), rows = [];
26695
- for (let i = map.height; i < height; i++) rows.push(emptyRow);
26696
- tr.insert(tr.mapping.slice(mapFrom).map(start + table.nodeSize - 2), rows);
26697
- }
26698
- return !!(empty || emptyHead);
26923
+ const schema = tr.doc.type.schema;
26924
+ const types = tableNodeTypes(schema);
26925
+ let empty;
26926
+ let emptyHead;
26927
+ if (width > map.width) for (let row = 0, rowEnd = 0; row < map.height; row++) {
26928
+ const rowNode = table.child(row);
26929
+ rowEnd += rowNode.nodeSize;
26930
+ const cells = [];
26931
+ let add;
26932
+ if (rowNode.lastChild == null || rowNode.lastChild.type == types.cell) add = empty || (empty = types.cell.createAndFill());
26933
+ else add = emptyHead || (emptyHead = types.header_cell.createAndFill());
26934
+ for (let i = map.width; i < width; i++) cells.push(add);
26935
+ tr.insert(tr.mapping.slice(mapFrom).map(rowEnd - 1 + start), cells);
26936
+ }
26937
+ if (height > map.height) {
26938
+ const cells = [];
26939
+ for (let i = 0, start$1 = (map.height - 1) * map.width; i < Math.max(map.width, width); i++) {
26940
+ const header = i >= map.width ? false : table.nodeAt(map.map[start$1 + i]).type == types.header_cell;
26941
+ cells.push(header ? emptyHead || (emptyHead = types.header_cell.createAndFill()) : empty || (empty = types.cell.createAndFill()));
26942
+ }
26943
+ const emptyRow = types.row.create(null, Fragment.from(cells)), rows = [];
26944
+ for (let i = map.height; i < height; i++) rows.push(emptyRow);
26945
+ tr.insert(tr.mapping.slice(mapFrom).map(start + table.nodeSize - 2), rows);
26946
+ }
26947
+ return !!(empty || emptyHead);
26699
26948
  }
26700
26949
  function isolateHorizontal(tr, map, table, start, left, right, top, mapFrom) {
26701
- if (top == 0 || top == map.height) return false;
26702
- let found = false;
26703
- for (let col = left; col < right; col++) {
26704
- const index = top * map.width + col, pos = map.map[index];
26705
- if (map.map[index - map.width] == pos) {
26706
- found = true;
26707
- const cell = table.nodeAt(pos);
26708
- const { top: cellTop, left: cellLeft } = map.findCell(pos);
26709
- tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + start), null, {
26710
- ...cell.attrs,
26711
- rowspan: top - cellTop
26712
- });
26713
- tr.insert(
26714
- tr.mapping.slice(mapFrom).map(map.positionAt(top, cellLeft, table)),
26715
- cell.type.createAndFill({
26716
- ...cell.attrs,
26717
- rowspan: cellTop + cell.attrs.rowspan - top
26718
- })
26719
- );
26720
- col += cell.attrs.colspan - 1;
26721
- }
26722
- }
26723
- return found;
26950
+ if (top == 0 || top == map.height) return false;
26951
+ let found = false;
26952
+ for (let col = left; col < right; col++) {
26953
+ const index = top * map.width + col, pos = map.map[index];
26954
+ if (map.map[index - map.width] == pos) {
26955
+ found = true;
26956
+ const cell = table.nodeAt(pos);
26957
+ const { top: cellTop, left: cellLeft } = map.findCell(pos);
26958
+ tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + start), null, {
26959
+ ...cell.attrs,
26960
+ rowspan: top - cellTop
26961
+ });
26962
+ tr.insert(tr.mapping.slice(mapFrom).map(map.positionAt(top, cellLeft, table)), cell.type.createAndFill({
26963
+ ...cell.attrs,
26964
+ rowspan: cellTop + cell.attrs.rowspan - top
26965
+ }));
26966
+ col += cell.attrs.colspan - 1;
26967
+ }
26968
+ }
26969
+ return found;
26724
26970
  }
26725
26971
  function isolateVertical(tr, map, table, start, top, bottom, left, mapFrom) {
26726
- if (left == 0 || left == map.width) return false;
26727
- let found = false;
26728
- for (let row = top; row < bottom; row++) {
26729
- const index = row * map.width + left, pos = map.map[index];
26730
- if (map.map[index - 1] == pos) {
26731
- found = true;
26732
- const cell = table.nodeAt(pos);
26733
- const cellLeft = map.colCount(pos);
26734
- const updatePos = tr.mapping.slice(mapFrom).map(pos + start);
26735
- tr.setNodeMarkup(
26736
- updatePos,
26737
- null,
26738
- removeColSpan(
26739
- cell.attrs,
26740
- left - cellLeft,
26741
- cell.attrs.colspan - (left - cellLeft)
26742
- )
26743
- );
26744
- tr.insert(
26745
- updatePos + cell.nodeSize,
26746
- cell.type.createAndFill(
26747
- removeColSpan(cell.attrs, 0, left - cellLeft)
26748
- )
26749
- );
26750
- row += cell.attrs.rowspan - 1;
26751
- }
26752
- }
26753
- return found;
26972
+ if (left == 0 || left == map.width) return false;
26973
+ let found = false;
26974
+ for (let row = top; row < bottom; row++) {
26975
+ const index = row * map.width + left, pos = map.map[index];
26976
+ if (map.map[index - 1] == pos) {
26977
+ found = true;
26978
+ const cell = table.nodeAt(pos);
26979
+ const cellLeft = map.colCount(pos);
26980
+ const updatePos = tr.mapping.slice(mapFrom).map(pos + start);
26981
+ tr.setNodeMarkup(updatePos, null, removeColSpan(cell.attrs, left - cellLeft, cell.attrs.colspan - (left - cellLeft)));
26982
+ tr.insert(updatePos + cell.nodeSize, cell.type.createAndFill(removeColSpan(cell.attrs, 0, left - cellLeft)));
26983
+ row += cell.attrs.rowspan - 1;
26984
+ }
26985
+ }
26986
+ return found;
26754
26987
  }
26988
+ /**
26989
+ * Insert the given set of cells (as returned by `pastedCells`) into a
26990
+ * table, at the position pointed at by rect.
26991
+ *
26992
+ * @internal
26993
+ */
26755
26994
  function insertCells(state, dispatch, tableStart, rect, cells) {
26756
- let table = tableStart ? state.doc.nodeAt(tableStart - 1) : state.doc;
26757
- if (!table) {
26758
- throw new Error("No table found");
26759
- }
26760
- let map = TableMap.get(table);
26761
- const { top, left } = rect;
26762
- const right = left + cells.width, bottom = top + cells.height;
26763
- const tr = state.tr;
26764
- let mapFrom = 0;
26765
- function recomp() {
26766
- table = tableStart ? tr.doc.nodeAt(tableStart - 1) : tr.doc;
26767
- if (!table) {
26768
- throw new Error("No table found");
26769
- }
26770
- map = TableMap.get(table);
26771
- mapFrom = tr.mapping.maps.length;
26772
- }
26773
- if (growTable(tr, map, table, tableStart, right, bottom, mapFrom)) recomp();
26774
- if (isolateHorizontal(tr, map, table, tableStart, left, right, top, mapFrom))
26775
- recomp();
26776
- if (isolateHorizontal(tr, map, table, tableStart, left, right, bottom, mapFrom))
26777
- recomp();
26778
- if (isolateVertical(tr, map, table, tableStart, top, bottom, left, mapFrom))
26779
- recomp();
26780
- if (isolateVertical(tr, map, table, tableStart, top, bottom, right, mapFrom))
26781
- recomp();
26782
- for (let row = top; row < bottom; row++) {
26783
- const from = map.positionAt(row, left, table), to = map.positionAt(row, right, table);
26784
- tr.replace(
26785
- tr.mapping.slice(mapFrom).map(from + tableStart),
26786
- tr.mapping.slice(mapFrom).map(to + tableStart),
26787
- new Slice(cells.rows[row - top], 0, 0)
26788
- );
26789
- }
26790
- recomp();
26791
- tr.setSelection(
26792
- new CellSelection(
26793
- tr.doc.resolve(tableStart + map.positionAt(top, left, table)),
26794
- tr.doc.resolve(tableStart + map.positionAt(bottom - 1, right - 1, table))
26795
- )
26796
- );
26797
- dispatch(tr);
26798
- }
26799
-
26800
- // src/input.ts
26801
- var handleKeyDown = keydownHandler({
26802
- ArrowLeft: arrow("horiz", -1),
26803
- ArrowRight: arrow("horiz", 1),
26804
- ArrowUp: arrow("vert", -1),
26805
- ArrowDown: arrow("vert", 1),
26806
- "Shift-ArrowLeft": shiftArrow("horiz", -1),
26807
- "Shift-ArrowRight": shiftArrow("horiz", 1),
26808
- "Shift-ArrowUp": shiftArrow("vert", -1),
26809
- "Shift-ArrowDown": shiftArrow("vert", 1),
26810
- Backspace: deleteCellSelection,
26811
- "Mod-Backspace": deleteCellSelection,
26812
- Delete: deleteCellSelection,
26813
- "Mod-Delete": deleteCellSelection
26995
+ let table = tableStart ? state.doc.nodeAt(tableStart - 1) : state.doc;
26996
+ if (!table) throw new Error("No table found");
26997
+ let map = TableMap.get(table);
26998
+ const { top, left } = rect;
26999
+ const right = left + cells.width, bottom = top + cells.height;
27000
+ const tr = state.tr;
27001
+ let mapFrom = 0;
27002
+ function recomp() {
27003
+ table = tableStart ? tr.doc.nodeAt(tableStart - 1) : tr.doc;
27004
+ if (!table) throw new Error("No table found");
27005
+ map = TableMap.get(table);
27006
+ mapFrom = tr.mapping.maps.length;
27007
+ }
27008
+ if (growTable(tr, map, table, tableStart, right, bottom, mapFrom)) recomp();
27009
+ if (isolateHorizontal(tr, map, table, tableStart, left, right, top, mapFrom)) recomp();
27010
+ if (isolateHorizontal(tr, map, table, tableStart, left, right, bottom, mapFrom)) recomp();
27011
+ if (isolateVertical(tr, map, table, tableStart, top, bottom, left, mapFrom)) recomp();
27012
+ if (isolateVertical(tr, map, table, tableStart, top, bottom, right, mapFrom)) recomp();
27013
+ for (let row = top; row < bottom; row++) {
27014
+ const from = map.positionAt(row, left, table), to = map.positionAt(row, right, table);
27015
+ tr.replace(tr.mapping.slice(mapFrom).map(from + tableStart), tr.mapping.slice(mapFrom).map(to + tableStart), new Slice(cells.rows[row - top], 0, 0));
27016
+ }
27017
+ recomp();
27018
+ tr.setSelection(new CellSelection(tr.doc.resolve(tableStart + map.positionAt(top, left, table)), tr.doc.resolve(tableStart + map.positionAt(bottom - 1, right - 1, table))));
27019
+ dispatch(tr);
27020
+ }
27021
+
27022
+ //#endregion
27023
+ //#region src/input.ts
27024
+ const handleKeyDown = keydownHandler({
27025
+ ArrowLeft: arrow("horiz", -1),
27026
+ ArrowRight: arrow("horiz", 1),
27027
+ ArrowUp: arrow("vert", -1),
27028
+ ArrowDown: arrow("vert", 1),
27029
+ "Shift-ArrowLeft": shiftArrow("horiz", -1),
27030
+ "Shift-ArrowRight": shiftArrow("horiz", 1),
27031
+ "Shift-ArrowUp": shiftArrow("vert", -1),
27032
+ "Shift-ArrowDown": shiftArrow("vert", 1),
27033
+ Backspace: deleteCellSelection,
27034
+ "Mod-Backspace": deleteCellSelection,
27035
+ Delete: deleteCellSelection,
27036
+ "Mod-Delete": deleteCellSelection
26814
27037
  });
26815
27038
  function maybeSetSelection(state, dispatch, selection) {
26816
- if (selection.eq(state.selection)) return false;
26817
- if (dispatch) dispatch(state.tr.setSelection(selection).scrollIntoView());
26818
- return true;
27039
+ if (selection.eq(state.selection)) return false;
27040
+ if (dispatch) dispatch(state.tr.setSelection(selection).scrollIntoView());
27041
+ return true;
26819
27042
  }
27043
+ /**
27044
+ * @internal
27045
+ */
26820
27046
  function arrow(axis, dir) {
26821
- return (state, dispatch, view) => {
26822
- if (!view) return false;
26823
- const sel = state.selection;
26824
- if (sel instanceof CellSelection) {
26825
- return maybeSetSelection(
26826
- state,
26827
- dispatch,
26828
- Selection.near(sel.$headCell, dir)
26829
- );
26830
- }
26831
- if (axis != "horiz" && !sel.empty) return false;
26832
- const end = atEndOfCell(view, axis, dir);
26833
- if (end == null) return false;
26834
- if (axis == "horiz") {
26835
- return maybeSetSelection(
26836
- state,
26837
- dispatch,
26838
- Selection.near(state.doc.resolve(sel.head + dir), dir)
26839
- );
26840
- } else {
26841
- const $cell = state.doc.resolve(end);
26842
- const $next = nextCell($cell, axis, dir);
26843
- let newSel;
26844
- if ($next) newSel = Selection.near($next, 1);
26845
- else if (dir < 0)
26846
- newSel = Selection.near(state.doc.resolve($cell.before(-1)), -1);
26847
- else newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1);
26848
- return maybeSetSelection(state, dispatch, newSel);
26849
- }
26850
- };
27047
+ return (state, dispatch, view) => {
27048
+ if (!view) return false;
27049
+ const sel = state.selection;
27050
+ if (sel instanceof CellSelection) return maybeSetSelection(state, dispatch, Selection.near(sel.$headCell, dir));
27051
+ if (axis != "horiz" && !sel.empty) return false;
27052
+ const end = atEndOfCell(view, axis, dir);
27053
+ if (end == null) return false;
27054
+ if (axis == "horiz") return maybeSetSelection(state, dispatch, Selection.near(state.doc.resolve(sel.head + dir), dir));
27055
+ else {
27056
+ const $cell = state.doc.resolve(end);
27057
+ const $next = nextCell($cell, axis, dir);
27058
+ let newSel;
27059
+ if ($next) newSel = Selection.near($next, 1);
27060
+ else if (dir < 0) newSel = Selection.near(state.doc.resolve($cell.before(-1)), -1);
27061
+ else newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1);
27062
+ return maybeSetSelection(state, dispatch, newSel);
27063
+ }
27064
+ };
26851
27065
  }
26852
27066
  function shiftArrow(axis, dir) {
26853
- return (state, dispatch, view) => {
26854
- if (!view) return false;
26855
- const sel = state.selection;
26856
- let cellSel;
26857
- if (sel instanceof CellSelection) {
26858
- cellSel = sel;
26859
- } else {
26860
- const end = atEndOfCell(view, axis, dir);
26861
- if (end == null) return false;
26862
- cellSel = new CellSelection(state.doc.resolve(end));
26863
- }
26864
- const $head = nextCell(cellSel.$headCell, axis, dir);
26865
- if (!$head) return false;
26866
- return maybeSetSelection(
26867
- state,
26868
- dispatch,
26869
- new CellSelection(cellSel.$anchorCell, $head)
26870
- );
26871
- };
27067
+ return (state, dispatch, view) => {
27068
+ if (!view) return false;
27069
+ const sel = state.selection;
27070
+ let cellSel;
27071
+ if (sel instanceof CellSelection) cellSel = sel;
27072
+ else {
27073
+ const end = atEndOfCell(view, axis, dir);
27074
+ if (end == null) return false;
27075
+ cellSel = new CellSelection(state.doc.resolve(end));
27076
+ }
27077
+ const $head = nextCell(cellSel.$headCell, axis, dir);
27078
+ if (!$head) return false;
27079
+ return maybeSetSelection(state, dispatch, new CellSelection(cellSel.$anchorCell, $head));
27080
+ };
26872
27081
  }
26873
27082
  function handleTripleClick(view, pos) {
26874
- const doc = view.state.doc, $cell = cellAround(doc.resolve(pos));
26875
- if (!$cell) return false;
26876
- view.dispatch(view.state.tr.setSelection(new CellSelection($cell)));
26877
- return true;
27083
+ const doc = view.state.doc, $cell = cellAround(doc.resolve(pos));
27084
+ if (!$cell) return false;
27085
+ view.dispatch(view.state.tr.setSelection(new CellSelection($cell)));
27086
+ return true;
26878
27087
  }
27088
+ /**
27089
+ * @public
27090
+ */
26879
27091
  function handlePaste(view, _, slice) {
26880
- if (!isInTable(view.state)) return false;
26881
- let cells = pastedCells(slice);
26882
- const sel = view.state.selection;
26883
- if (sel instanceof CellSelection) {
26884
- if (!cells)
26885
- cells = {
26886
- width: 1,
26887
- height: 1,
26888
- rows: [
26889
- Fragment.from(
26890
- fitSlice(tableNodeTypes(view.state.schema).cell, slice)
26891
- )
26892
- ]
26893
- };
26894
- const table = sel.$anchorCell.node(-1);
26895
- const start = sel.$anchorCell.start(-1);
26896
- const rect = TableMap.get(table).rectBetween(
26897
- sel.$anchorCell.pos - start,
26898
- sel.$headCell.pos - start
26899
- );
26900
- cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top);
26901
- insertCells(view.state, view.dispatch, start, rect, cells);
26902
- return true;
26903
- } else if (cells) {
26904
- const $cell = selectionCell(view.state);
26905
- const start = $cell.start(-1);
26906
- insertCells(
26907
- view.state,
26908
- view.dispatch,
26909
- start,
26910
- TableMap.get($cell.node(-1)).findCell($cell.pos - start),
26911
- cells
26912
- );
26913
- return true;
26914
- } else {
26915
- return false;
26916
- }
26917
- }
26918
- function handleMouseDown(view, startEvent) {
26919
- var _a;
26920
- if (startEvent.ctrlKey || startEvent.metaKey) return;
26921
- const startDOMCell = domInCell(view, startEvent.target);
26922
- let $anchor;
26923
- if (startEvent.shiftKey && view.state.selection instanceof CellSelection) {
26924
- setCellSelection(view.state.selection.$anchorCell, startEvent);
26925
- startEvent.preventDefault();
26926
- } else if (startEvent.shiftKey && startDOMCell && ($anchor = cellAround(view.state.selection.$anchor)) != null && ((_a = cellUnderMouse(view, startEvent)) == null ? void 0 : _a.pos) != $anchor.pos) {
26927
- setCellSelection($anchor, startEvent);
26928
- startEvent.preventDefault();
26929
- } else if (!startDOMCell) {
26930
- return;
26931
- }
26932
- function setCellSelection($anchor2, event) {
26933
- let $head = cellUnderMouse(view, event);
26934
- const starting = tableEditingKey.getState(view.state) == null;
26935
- if (!$head || !inSameTable($anchor2, $head)) {
26936
- if (starting) $head = $anchor2;
26937
- else return;
26938
- }
26939
- const selection = new CellSelection($anchor2, $head);
26940
- if (starting || !view.state.selection.eq(selection)) {
26941
- const tr = view.state.tr.setSelection(selection);
26942
- if (starting) tr.setMeta(tableEditingKey, $anchor2.pos);
26943
- view.dispatch(tr);
26944
- }
26945
- }
26946
- function stop() {
26947
- view.root.removeEventListener("mouseup", stop);
26948
- view.root.removeEventListener("dragstart", stop);
26949
- view.root.removeEventListener("mousemove", move);
26950
- if (tableEditingKey.getState(view.state) != null)
26951
- view.dispatch(view.state.tr.setMeta(tableEditingKey, -1));
26952
- }
26953
- function move(_event) {
26954
- const event = _event;
26955
- const anchor = tableEditingKey.getState(view.state);
26956
- let $anchor2;
26957
- if (anchor != null) {
26958
- $anchor2 = view.state.doc.resolve(anchor);
26959
- } else if (domInCell(view, event.target) != startDOMCell) {
26960
- $anchor2 = cellUnderMouse(view, startEvent);
26961
- if (!$anchor2) return stop();
26962
- }
26963
- if ($anchor2) setCellSelection($anchor2, event);
26964
- }
26965
- view.root.addEventListener("mouseup", stop);
26966
- view.root.addEventListener("dragstart", stop);
26967
- view.root.addEventListener("mousemove", move);
27092
+ if (!isInTable(view.state)) return false;
27093
+ let cells = pastedCells(slice);
27094
+ const sel = view.state.selection;
27095
+ if (sel instanceof CellSelection) {
27096
+ if (!cells) cells = {
27097
+ width: 1,
27098
+ height: 1,
27099
+ rows: [Fragment.from(fitSlice(tableNodeTypes(view.state.schema).cell, slice))]
27100
+ };
27101
+ const table = sel.$anchorCell.node(-1);
27102
+ const start = sel.$anchorCell.start(-1);
27103
+ const rect = TableMap.get(table).rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start);
27104
+ cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top);
27105
+ insertCells(view.state, view.dispatch, start, rect, cells);
27106
+ return true;
27107
+ } else if (cells) {
27108
+ const $cell = selectionCell(view.state);
27109
+ const start = $cell.start(-1);
27110
+ insertCells(view.state, view.dispatch, start, TableMap.get($cell.node(-1)).findCell($cell.pos - start), cells);
27111
+ return true;
27112
+ } else return false;
27113
+ }
27114
+ function handleMouseDown$1(view, startEvent) {
27115
+ var _cellUnderMouse;
27116
+ if (startEvent.button != 0) return;
27117
+ if (startEvent.ctrlKey || startEvent.metaKey) return;
27118
+ const startDOMCell = domInCell(view, startEvent.target);
27119
+ let $anchor;
27120
+ if (startEvent.shiftKey && view.state.selection instanceof CellSelection) {
27121
+ setCellSelection(view.state.selection.$anchorCell, startEvent);
27122
+ startEvent.preventDefault();
27123
+ } else if (startEvent.shiftKey && startDOMCell && ($anchor = cellAround(view.state.selection.$anchor)) != null && ((_cellUnderMouse = cellUnderMouse(view, startEvent)) === null || _cellUnderMouse === void 0 ? void 0 : _cellUnderMouse.pos) != $anchor.pos) {
27124
+ setCellSelection($anchor, startEvent);
27125
+ startEvent.preventDefault();
27126
+ } else if (!startDOMCell) return;
27127
+ function setCellSelection($anchor$1, event) {
27128
+ let $head = cellUnderMouse(view, event);
27129
+ const starting = tableEditingKey.getState(view.state) == null;
27130
+ if (!$head || !inSameTable($anchor$1, $head)) if (starting) $head = $anchor$1;
27131
+ else return;
27132
+ const selection = new CellSelection($anchor$1, $head);
27133
+ if (starting || !view.state.selection.eq(selection)) {
27134
+ const tr = view.state.tr.setSelection(selection);
27135
+ if (starting) tr.setMeta(tableEditingKey, $anchor$1.pos);
27136
+ view.dispatch(tr);
27137
+ }
27138
+ }
27139
+ function stop() {
27140
+ view.root.removeEventListener("mouseup", stop);
27141
+ view.root.removeEventListener("dragstart", stop);
27142
+ view.root.removeEventListener("mousemove", move);
27143
+ if (tableEditingKey.getState(view.state) != null) view.dispatch(view.state.tr.setMeta(tableEditingKey, -1));
27144
+ }
27145
+ function move(_event) {
27146
+ const event = _event;
27147
+ const anchor = tableEditingKey.getState(view.state);
27148
+ let $anchor$1;
27149
+ if (anchor != null) $anchor$1 = view.state.doc.resolve(anchor);
27150
+ else if (domInCell(view, event.target) != startDOMCell) {
27151
+ $anchor$1 = cellUnderMouse(view, startEvent);
27152
+ if (!$anchor$1) return stop();
27153
+ }
27154
+ if ($anchor$1) setCellSelection($anchor$1, event);
27155
+ }
27156
+ view.root.addEventListener("mouseup", stop);
27157
+ view.root.addEventListener("dragstart", stop);
27158
+ view.root.addEventListener("mousemove", move);
26968
27159
  }
26969
27160
  function atEndOfCell(view, axis, dir) {
26970
- if (!(view.state.selection instanceof TextSelection)) return null;
26971
- const { $head } = view.state.selection;
26972
- for (let d = $head.depth - 1; d >= 0; d--) {
26973
- const parent = $head.node(d), index = dir < 0 ? $head.index(d) : $head.indexAfter(d);
26974
- if (index != (dir < 0 ? 0 : parent.childCount)) return null;
26975
- if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") {
26976
- const cellPos = $head.before(d);
26977
- const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
26978
- return view.endOfTextblock(dirStr) ? cellPos : null;
26979
- }
26980
- }
26981
- return null;
27161
+ if (!(view.state.selection instanceof TextSelection)) return null;
27162
+ const { $head } = view.state.selection;
27163
+ for (let d = $head.depth - 1; d >= 0; d--) {
27164
+ const parent = $head.node(d);
27165
+ if ((dir < 0 ? $head.index(d) : $head.indexAfter(d)) != (dir < 0 ? 0 : parent.childCount)) return null;
27166
+ if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") {
27167
+ const cellPos = $head.before(d);
27168
+ const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
27169
+ return view.endOfTextblock(dirStr) ? cellPos : null;
27170
+ }
27171
+ }
27172
+ return null;
26982
27173
  }
26983
27174
  function domInCell(view, dom) {
26984
- for (; dom && dom != view.dom; dom = dom.parentNode) {
26985
- if (dom.nodeName == "TD" || dom.nodeName == "TH") {
26986
- return dom;
26987
- }
26988
- }
26989
- return null;
27175
+ for (; dom && dom != view.dom; dom = dom.parentNode) if (dom.nodeName == "TD" || dom.nodeName == "TH") return dom;
27176
+ return null;
26990
27177
  }
26991
27178
  function cellUnderMouse(view, event) {
26992
- const mousePos = view.posAtCoords({
26993
- left: event.clientX,
26994
- top: event.clientY
26995
- });
26996
- if (!mousePos) return null;
26997
- return mousePos ? cellAround(view.state.doc.resolve(mousePos.pos)) : null;
26998
- }
26999
-
27000
- // src/columnresizing.ts
27001
- new PluginKey(
27002
- "tableColumnResizing"
27003
- );
27004
-
27005
- // src/index.ts
27006
- function tableEditing({
27007
- allowTableNodeSelection = false
27008
- } = {}) {
27009
- return new Plugin({
27010
- key: tableEditingKey,
27011
- // This piece of state is used to remember when a mouse-drag
27012
- // cell-selection is happening, so that it can continue even as
27013
- // transactions (which might move its anchor cell) come in.
27014
- state: {
27015
- init() {
27016
- return null;
27017
- },
27018
- apply(tr, cur) {
27019
- const set = tr.getMeta(tableEditingKey);
27020
- if (set != null) return set == -1 ? null : set;
27021
- if (cur == null || !tr.docChanged) return cur;
27022
- const { deleted, pos } = tr.mapping.mapResult(cur);
27023
- return deleted ? null : pos;
27024
- }
27025
- },
27026
- props: {
27027
- decorations: drawCellSelection,
27028
- handleDOMEvents: {
27029
- mousedown: handleMouseDown
27030
- },
27031
- createSelectionBetween(view) {
27032
- return tableEditingKey.getState(view.state) != null ? view.state.selection : null;
27033
- },
27034
- handleTripleClick,
27035
- handleKeyDown,
27036
- handlePaste
27037
- },
27038
- appendTransaction(_, oldState, state) {
27039
- return normalizeSelection(
27040
- state,
27041
- fixTables(state, oldState),
27042
- allowTableNodeSelection
27043
- );
27044
- }
27045
- });
27179
+ const mousePos = view.posAtCoords({
27180
+ left: event.clientX,
27181
+ top: event.clientY
27182
+ });
27183
+ if (!mousePos) return null;
27184
+ let { inside, pos } = mousePos;
27185
+ return inside >= 0 && cellAround(view.state.doc.resolve(inside)) || cellAround(view.state.doc.resolve(pos));
27186
+ }
27187
+
27188
+ //#endregion
27189
+ //#region src/columnresizing.ts
27190
+ /**
27191
+ * @public
27192
+ */
27193
+ new PluginKey("tableColumnResizing");
27194
+
27195
+ //#endregion
27196
+ //#region src/index.ts
27197
+ /**
27198
+ * Creates a [plugin](http://prosemirror.net/docs/ref/#state.Plugin)
27199
+ * that, when added to an editor, enables cell-selection, handles
27200
+ * cell-based copy/paste, and makes sure tables stay well-formed (each
27201
+ * row has the same width, and cells don't overlap).
27202
+ *
27203
+ * You should probably put this plugin near the end of your array of
27204
+ * plugins, since it handles mouse and arrow key events in tables
27205
+ * rather broadly, and other plugins, like the gap cursor or the
27206
+ * column-width dragging plugin, might want to get a turn first to
27207
+ * perform more specific behavior.
27208
+ *
27209
+ * @public
27210
+ */
27211
+ function tableEditing({ allowTableNodeSelection = false } = {}) {
27212
+ return new Plugin({
27213
+ key: tableEditingKey,
27214
+ state: {
27215
+ init() {
27216
+ return null;
27217
+ },
27218
+ apply(tr, cur) {
27219
+ const set = tr.getMeta(tableEditingKey);
27220
+ if (set != null) return set == -1 ? null : set;
27221
+ if (cur == null || !tr.docChanged) return cur;
27222
+ const { deleted, pos } = tr.mapping.mapResult(cur);
27223
+ return deleted ? null : pos;
27224
+ }
27225
+ },
27226
+ props: {
27227
+ decorations: drawCellSelection,
27228
+ handleDOMEvents: { mousedown: handleMouseDown$1 },
27229
+ createSelectionBetween(view) {
27230
+ return tableEditingKey.getState(view.state) != null ? view.state.selection : null;
27231
+ },
27232
+ handleTripleClick,
27233
+ handleKeyDown,
27234
+ handlePaste
27235
+ },
27236
+ appendTransaction(_, oldState, state) {
27237
+ return normalizeSelection(state, fixTables(state, oldState), allowTableNodeSelection);
27238
+ }
27239
+ });
27046
27240
  }
27047
27241
 
27048
27242
  const getTableEditingPlugins = (tablesEnabled) => {
@@ -27419,7 +27613,7 @@ const ProsemirrorAdapter = class {
27419
27613
  (_e = this.view) === null || _e === void 0 ? void 0 : _e.destroy();
27420
27614
  }
27421
27615
  render() {
27422
- return (h(Host, { key: '96595c30eb3786d8bd8caf69b323545cb5312bbe', onFocus: this.handleFocus }, h("div", { key: '10f3cc5a289efb6c70f91771264188309143acb3', id: "editor" }), this.renderToolbar(), this.renderLinkMenu()));
27616
+ return (h(Host, { key: '23d1370fa319f2cca982c72d09a01d69ac26008e', onFocus: this.handleFocus }, h("div", { key: 'f3be546259d31156dde04c4f6e4e8b9bdacd68aa', id: "editor" }), this.renderToolbar(), this.renderLinkMenu()));
27423
27617
  }
27424
27618
  renderToolbar() {
27425
27619
  if (this.actionBarItems.length === 0 || this.ui === 'no-toolbar') {