@shelamkoff/rector 1.0.0

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 (668) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +17 -0
  3. package/README.md +23 -0
  4. package/THIRD_PARTY_LICENSES.txt +298 -0
  5. package/dist/I18n.d.ts +1 -0
  6. package/dist/core/Block.d.ts +110 -0
  7. package/dist/core/Block.js +390 -0
  8. package/dist/core/BlockAnimator.d.ts +39 -0
  9. package/dist/core/BlockAnimator.js +106 -0
  10. package/dist/core/BlockManager.d.ts +163 -0
  11. package/dist/core/BlockManager.js +640 -0
  12. package/dist/core/BlockOperations.d.ts +67 -0
  13. package/dist/core/BlockOperations.js +238 -0
  14. package/dist/core/ChangeNotifier.d.ts +15 -0
  15. package/dist/core/ChangeNotifier.js +55 -0
  16. package/dist/core/CommandDispatcher.d.ts +52 -0
  17. package/dist/core/CommandDispatcher.js +208 -0
  18. package/dist/core/CrossBlockSelection.d.ts +30 -0
  19. package/dist/core/CrossBlockSelection.js +74 -0
  20. package/dist/core/Diagnostics.d.ts +23 -0
  21. package/dist/core/Diagnostics.js +62 -0
  22. package/dist/core/DocumentSchema.d.ts +29 -0
  23. package/dist/core/DocumentSchema.js +147 -0
  24. package/dist/core/DocumentSnapshotStore.d.ts +34 -0
  25. package/dist/core/DocumentSnapshotStore.js +153 -0
  26. package/dist/core/DragManager.d.ts +17 -0
  27. package/dist/core/DragManager.js +223 -0
  28. package/dist/core/EditorFacade.d.ts +154 -0
  29. package/dist/core/EditorFacade.js +361 -0
  30. package/dist/core/EditorHolderOwnership.d.ts +12 -0
  31. package/dist/core/EditorHolderOwnership.js +28 -0
  32. package/dist/core/I18n.d.ts +147 -0
  33. package/dist/core/I18n.js +296 -0
  34. package/dist/core/InlinePatternMatcher.d.ts +26 -0
  35. package/dist/core/InlinePatternMatcher.js +267 -0
  36. package/dist/core/InlinePluginRegistry.d.ts +55 -0
  37. package/dist/core/InlinePluginRegistry.js +128 -0
  38. package/dist/core/KeyboardManager.d.ts +17 -0
  39. package/dist/core/KeyboardManager.js +231 -0
  40. package/dist/core/LifecycleScope.d.ts +19 -0
  41. package/dist/core/LifecycleScope.js +41 -0
  42. package/dist/core/MouseSelectionManager.d.ts +30 -0
  43. package/dist/core/MouseSelectionManager.js +307 -0
  44. package/dist/core/PluginOwnership.d.ts +9 -0
  45. package/dist/core/PluginOwnership.js +40 -0
  46. package/dist/core/PopupManager.d.ts +50 -0
  47. package/dist/core/PopupManager.js +183 -0
  48. package/dist/core/PreservedBlockPlugin.d.ts +11 -0
  49. package/dist/core/PreservedBlockPlugin.js +42 -0
  50. package/dist/core/PublicEditorApi.d.ts +82 -0
  51. package/dist/core/PublicEditorApi.js +158 -0
  52. package/dist/core/SelectionManager.d.ts +50 -0
  53. package/dist/core/SelectionManager.js +205 -0
  54. package/dist/core/ShortcutRegistry.d.ts +29 -0
  55. package/dist/core/ShortcutRegistry.js +106 -0
  56. package/dist/core/SlashCommands.d.ts +34 -0
  57. package/dist/core/SlashCommands.js +483 -0
  58. package/dist/core/StyleInjector.d.ts +1 -0
  59. package/dist/core/StyleInjector.js +1 -0
  60. package/dist/core/Tooltip.d.ts +17 -0
  61. package/dist/core/Tooltip.js +60 -0
  62. package/dist/core/TriggerManager.d.ts +17 -0
  63. package/dist/core/TriggerManager.js +159 -0
  64. package/dist/core/TypeSelector.d.ts +31 -0
  65. package/dist/core/TypeSelector.js +464 -0
  66. package/dist/core/UndoManager.d.ts +72 -0
  67. package/dist/core/UndoManager.js +383 -0
  68. package/dist/core/block-settings-menu/BlockActions.d.ts +81 -0
  69. package/dist/core/block-settings-menu/BlockActions.js +233 -0
  70. package/dist/core/block-settings-menu/BlockSettingsMenu.d.ts +46 -0
  71. package/dist/core/block-settings-menu/BlockSettingsMenu.js +205 -0
  72. package/dist/core/block-settings-menu/MenuBuilder.d.ts +43 -0
  73. package/dist/core/block-settings-menu/MenuBuilder.js +203 -0
  74. package/dist/core/block-settings-menu/MenuPositioner.d.ts +22 -0
  75. package/dist/core/block-settings-menu/MenuPositioner.js +79 -0
  76. package/dist/core/clipboard/Clipboard.d.ts +47 -0
  77. package/dist/core/clipboard/Clipboard.js +653 -0
  78. package/dist/core/clipboard/CrossBlockEditor.d.ts +43 -0
  79. package/dist/core/clipboard/CrossBlockEditor.js +198 -0
  80. package/dist/core/clipboard/PasteRouter.d.ts +27 -0
  81. package/dist/core/clipboard/PasteRouter.js +86 -0
  82. package/dist/core/clipboard/pasteInsert.d.ts +35 -0
  83. package/dist/core/clipboard/pasteInsert.js +215 -0
  84. package/dist/core/clipboard/pasteUtils.d.ts +25 -0
  85. package/dist/core/clipboard/pasteUtils.js +98 -0
  86. package/dist/core/config.d.ts +77 -0
  87. package/dist/core/config.js +100 -0
  88. package/dist/core/constants.d.ts +23 -0
  89. package/dist/core/constants.js +30 -0
  90. package/dist/core/crossBlockConvert.d.ts +38 -0
  91. package/dist/core/crossBlockConvert.js +253 -0
  92. package/dist/core/dom.d.ts +35 -0
  93. package/dist/core/dom.js +65 -0
  94. package/dist/core/editorEvents.d.ts +89 -0
  95. package/dist/core/editorEvents.js +60 -0
  96. package/dist/core/hydrateInlinePlugins.d.ts +9 -0
  97. package/dist/core/hydrateInlinePlugins.js +36 -0
  98. package/dist/core/icons.d.ts +10 -0
  99. package/dist/core/icons.js +21 -0
  100. package/dist/core/index.d.ts +59 -0
  101. package/dist/core/index.js +703 -0
  102. package/dist/core/inline-toolbar/ActionsPanel.d.ts +61 -0
  103. package/dist/core/inline-toolbar/ActionsPanel.js +132 -0
  104. package/dist/core/inline-toolbar/InlinePositioner.d.ts +20 -0
  105. package/dist/core/inline-toolbar/InlinePositioner.js +63 -0
  106. package/dist/core/inline-toolbar/InlineToolbar.d.ts +45 -0
  107. package/dist/core/inline-toolbar/InlineToolbar.js +456 -0
  108. package/dist/core/inline-toolbar/PluginControlsSlot.d.ts +52 -0
  109. package/dist/core/inline-toolbar/PluginControlsSlot.js +118 -0
  110. package/dist/core/inline-toolbar/SelectionTracker.d.ts +63 -0
  111. package/dist/core/inline-toolbar/SelectionTracker.js +173 -0
  112. package/dist/core/inlinePluginInsert.d.ts +13 -0
  113. package/dist/core/inlinePluginInsert.js +56 -0
  114. package/dist/core/locale/en.d.ts +35 -0
  115. package/dist/core/locale/en.js +37 -0
  116. package/dist/core/locale/ru.d.ts +35 -0
  117. package/dist/core/locale/ru.js +37 -0
  118. package/dist/core/menuKeyboardNav.d.ts +15 -0
  119. package/dist/core/menuKeyboardNav.js +52 -0
  120. package/dist/core/sanitize.d.ts +2 -0
  121. package/dist/core/sanitize.js +6 -0
  122. package/dist/core/splitConvert.d.ts +46 -0
  123. package/dist/core/splitConvert.js +190 -0
  124. package/dist/core/textOffset.d.ts +46 -0
  125. package/dist/core/textOffset.js +180 -0
  126. package/dist/core/themes/dark.css +30 -0
  127. package/dist/core/themes/light.css +33 -0
  128. package/dist/core/themes/variables.css +1170 -0
  129. package/dist/core/toolbar/OffcanvasRoot.d.ts +37 -0
  130. package/dist/core/toolbar/OffcanvasRoot.js +127 -0
  131. package/dist/core/toolbar/Toolbar.d.ts +70 -0
  132. package/dist/core/toolbar/Toolbar.js +432 -0
  133. package/dist/core/toolbar/ToolbarPositioner.d.ts +60 -0
  134. package/dist/core/toolbar/ToolbarPositioner.js +188 -0
  135. package/dist/core/toolbar/ToolboxBuilder.d.ts +44 -0
  136. package/dist/core/toolbar/ToolboxBuilder.js +260 -0
  137. package/dist/core/types.d.ts +747 -0
  138. package/dist/core/uid.d.ts +6 -0
  139. package/dist/core/uid.js +29 -0
  140. package/dist/index.d.ts +2 -0
  141. package/dist/index.js +1 -0
  142. package/dist/inline-plugins/README.md +35 -0
  143. package/dist/inline-plugins/README.ru.md +35 -0
  144. package/dist/inline-plugins/color/README.md +61 -0
  145. package/dist/inline-plugins/color/README.ru.md +61 -0
  146. package/dist/inline-plugins/color.d.ts +8 -0
  147. package/dist/inline-plugins/color.js +184 -0
  148. package/dist/inline-plugins/locale/en.d.ts +7 -0
  149. package/dist/inline-plugins/locale/en.js +6 -0
  150. package/dist/inline-plugins/locale/ru.d.ts +7 -0
  151. package/dist/inline-plugins/locale/ru.js +6 -0
  152. package/dist/inline-plugins/mention/README.md +97 -0
  153. package/dist/inline-plugins/mention/README.ru.md +97 -0
  154. package/dist/inline-plugins/mention/index.d.ts +110 -0
  155. package/dist/inline-plugins/mention/index.js +1897 -0
  156. package/dist/inline-plugins/mention/styles.css +183 -0
  157. package/dist/inline-plugins/mention/widget.d.ts +16 -0
  158. package/dist/inline-plugins/mention/widget.js +75 -0
  159. package/dist/inline-tools/align.d.ts +14 -0
  160. package/dist/inline-tools/align.js +120 -0
  161. package/dist/inline-tools/bold.d.ts +8 -0
  162. package/dist/inline-tools/bold.js +12 -0
  163. package/dist/inline-tools/caseTransform.d.ts +8 -0
  164. package/dist/inline-tools/caseTransform.js +87 -0
  165. package/dist/inline-tools/clearFormatting.d.ts +8 -0
  166. package/dist/inline-tools/clearFormatting.js +74 -0
  167. package/dist/inline-tools/code.d.ts +8 -0
  168. package/dist/inline-tools/code.js +12 -0
  169. package/dist/inline-tools/colorPicker.d.ts +7 -0
  170. package/dist/inline-tools/colorPicker.js +271 -0
  171. package/dist/inline-tools/defaults.d.ts +10 -0
  172. package/dist/inline-tools/defaults.js +57 -0
  173. package/dist/inline-tools/fontSize.d.ts +7 -0
  174. package/dist/inline-tools/fontSize.js +524 -0
  175. package/dist/inline-tools/italic.d.ts +8 -0
  176. package/dist/inline-tools/italic.js +12 -0
  177. package/dist/inline-tools/link.d.ts +12 -0
  178. package/dist/inline-tools/link.js +251 -0
  179. package/dist/inline-tools/marker.d.ts +8 -0
  180. package/dist/inline-tools/marker.js +12 -0
  181. package/dist/inline-tools/scriptTool.d.ts +11 -0
  182. package/dist/inline-tools/scriptTool.js +149 -0
  183. package/dist/inline-tools/strikethrough.d.ts +8 -0
  184. package/dist/inline-tools/strikethrough.js +12 -0
  185. package/dist/inline-tools/utils.d.ts +220 -0
  186. package/dist/inline-tools/utils.js +992 -0
  187. package/dist/locale/en.d.ts +311 -0
  188. package/dist/locale/en.js +52 -0
  189. package/dist/locale/ru.d.ts +315 -0
  190. package/dist/locale/ru.js +52 -0
  191. package/dist/plugins/BlockPluginAbstract.d.ts +82 -0
  192. package/dist/plugins/BlockPluginAbstract.js +111 -0
  193. package/dist/plugins/README.md +44 -0
  194. package/dist/plugins/README.ru.md +40 -0
  195. package/dist/plugins/async.d.ts +35 -0
  196. package/dist/plugins/async.js +79 -0
  197. package/dist/plugins/attaches/README.md +86 -0
  198. package/dist/plugins/attaches/README.ru.md +87 -0
  199. package/dist/plugins/attaches/attaches.css +374 -0
  200. package/dist/plugins/attaches/index.d.ts +133 -0
  201. package/dist/plugins/attaches/index.js +921 -0
  202. package/dist/plugins/attaches/locale/en.d.ts +23 -0
  203. package/dist/plugins/attaches/locale/en.js +19 -0
  204. package/dist/plugins/attaches/locale/keys.d.ts +5 -0
  205. package/dist/plugins/attaches/locale/ru.d.ts +25 -0
  206. package/dist/plugins/attaches/locale/ru.js +19 -0
  207. package/dist/plugins/carousel/README.md +108 -0
  208. package/dist/plugins/carousel/README.ru.md +109 -0
  209. package/dist/plugins/carousel/carousel.css +198 -0
  210. package/dist/plugins/carousel/icons.d.ts +12 -0
  211. package/dist/plugins/carousel/icons.js +13 -0
  212. package/dist/plugins/carousel/index.d.ts +137 -0
  213. package/dist/plugins/carousel/index.js +859 -0
  214. package/dist/plugins/carousel/locale/en.d.ts +41 -0
  215. package/dist/plugins/carousel/locale/en.js +40 -0
  216. package/dist/plugins/carousel/locale/keys.d.ts +2 -0
  217. package/dist/plugins/carousel/locale/ru.d.ts +41 -0
  218. package/dist/plugins/carousel/locale/ru.js +40 -0
  219. package/dist/plugins/carousel/state.d.ts +29 -0
  220. package/dist/plugins/carousel/state.js +42 -0
  221. package/dist/plugins/checklist/README.md +54 -0
  222. package/dist/plugins/checklist/README.ru.md +55 -0
  223. package/dist/plugins/checklist/checklist.css +80 -0
  224. package/dist/plugins/checklist/index.d.ts +75 -0
  225. package/dist/plugins/checklist/index.js +407 -0
  226. package/dist/plugins/checklist/locale/en.d.ts +5 -0
  227. package/dist/plugins/checklist/locale/en.js +4 -0
  228. package/dist/plugins/checklist/locale/keys.d.ts +5 -0
  229. package/dist/plugins/checklist/locale/ru.d.ts +5 -0
  230. package/dist/plugins/checklist/locale/ru.js +4 -0
  231. package/dist/plugins/checklist/mapTextFields.d.ts +1 -0
  232. package/dist/plugins/checklist/mapTextFields.js +1 -0
  233. package/dist/plugins/code/README.md +59 -0
  234. package/dist/plugins/code/README.ru.md +60 -0
  235. package/dist/plugins/code/code.css +360 -0
  236. package/dist/plugins/code/index.d.ts +109 -0
  237. package/dist/plugins/code/index.js +1012 -0
  238. package/dist/plugins/code/locale/en.d.ts +11 -0
  239. package/dist/plugins/code/locale/en.js +10 -0
  240. package/dist/plugins/code/locale/keys.d.ts +5 -0
  241. package/dist/plugins/code/locale/ru.d.ts +11 -0
  242. package/dist/plugins/code/locale/ru.js +10 -0
  243. package/dist/plugins/columns/README.md +55 -0
  244. package/dist/plugins/columns/README.ru.md +56 -0
  245. package/dist/plugins/columns/columns.css +103 -0
  246. package/dist/plugins/columns/index.d.ts +58 -0
  247. package/dist/plugins/columns/index.js +236 -0
  248. package/dist/plugins/columns/locale/en.d.ts +6 -0
  249. package/dist/plugins/columns/locale/en.js +5 -0
  250. package/dist/plugins/columns/locale/keys.d.ts +5 -0
  251. package/dist/plugins/columns/locale/ru.d.ts +6 -0
  252. package/dist/plugins/columns/locale/ru.js +5 -0
  253. package/dist/plugins/delimiter/README.md +48 -0
  254. package/dist/plugins/delimiter/README.ru.md +49 -0
  255. package/dist/plugins/delimiter/delimiter.css +22 -0
  256. package/dist/plugins/delimiter/index.d.ts +38 -0
  257. package/dist/plugins/delimiter/index.js +69 -0
  258. package/dist/plugins/delimiter/locale/en.d.ts +4 -0
  259. package/dist/plugins/delimiter/locale/en.js +3 -0
  260. package/dist/plugins/delimiter/locale/keys.d.ts +5 -0
  261. package/dist/plugins/delimiter/locale/ru.d.ts +4 -0
  262. package/dist/plugins/delimiter/locale/ru.js +3 -0
  263. package/dist/plugins/embed/README.md +81 -0
  264. package/dist/plugins/embed/README.ru.md +82 -0
  265. package/dist/plugins/embed/embed.css +558 -0
  266. package/dist/plugins/embed/index.d.ts +271 -0
  267. package/dist/plugins/embed/index.js +967 -0
  268. package/dist/plugins/embed/locale/en.d.ts +20 -0
  269. package/dist/plugins/embed/locale/en.js +19 -0
  270. package/dist/plugins/embed/locale/keys.d.ts +5 -0
  271. package/dist/plugins/embed/locale/ru.d.ts +20 -0
  272. package/dist/plugins/embed/locale/ru.js +19 -0
  273. package/dist/plugins/embed/player.d.ts +1 -0
  274. package/dist/plugins/embed/player.js +1 -0
  275. package/dist/plugins/gallery/README.md +92 -0
  276. package/dist/plugins/gallery/README.ru.md +93 -0
  277. package/dist/plugins/gallery/css.d.ts +52 -0
  278. package/dist/plugins/gallery/css.js +67 -0
  279. package/dist/plugins/gallery/gallery.css +860 -0
  280. package/dist/plugins/gallery/icons.d.ts +13 -0
  281. package/dist/plugins/gallery/icons.js +45 -0
  282. package/dist/plugins/gallery/index.d.ts +126 -0
  283. package/dist/plugins/gallery/index.js +355 -0
  284. package/dist/plugins/gallery/layout.d.ts +35 -0
  285. package/dist/plugins/gallery/layout.js +79 -0
  286. package/dist/plugins/gallery/locale/en.d.ts +36 -0
  287. package/dist/plugins/gallery/locale/en.js +35 -0
  288. package/dist/plugins/gallery/locale/keys.d.ts +5 -0
  289. package/dist/plugins/gallery/locale/ru.d.ts +36 -0
  290. package/dist/plugins/gallery/locale/ru.js +35 -0
  291. package/dist/plugins/gallery/settings.d.ts +25 -0
  292. package/dist/plugins/gallery/settings.js +199 -0
  293. package/dist/plugins/gallery/slot.d.ts +73 -0
  294. package/dist/plugins/gallery/slot.js +260 -0
  295. package/dist/plugins/gallery/state.d.ts +67 -0
  296. package/dist/plugins/gallery/state.js +133 -0
  297. package/dist/plugins/gallery/styles.d.ts +10 -0
  298. package/dist/plugins/gallery/styles.js +24 -0
  299. package/dist/plugins/gallery/uploader.d.ts +31 -0
  300. package/dist/plugins/gallery/uploader.js +111 -0
  301. package/dist/plugins/gallery/view-empty.d.ts +41 -0
  302. package/dist/plugins/gallery/view-empty.js +56 -0
  303. package/dist/plugins/gallery/view-filled.d.ts +55 -0
  304. package/dist/plugins/gallery/view-filled.js +353 -0
  305. package/dist/plugins/heading/HeadingLevelSelect.d.ts +16 -0
  306. package/dist/plugins/heading/HeadingLevelSelect.js +183 -0
  307. package/dist/plugins/heading/README.md +58 -0
  308. package/dist/plugins/heading/README.ru.md +59 -0
  309. package/dist/plugins/heading/heading.css +76 -0
  310. package/dist/plugins/heading/index.d.ts +124 -0
  311. package/dist/plugins/heading/index.js +273 -0
  312. package/dist/plugins/heading/locale/en.d.ts +11 -0
  313. package/dist/plugins/heading/locale/en.js +10 -0
  314. package/dist/plugins/heading/locale/keys.d.ts +5 -0
  315. package/dist/plugins/heading/locale/ru.d.ts +11 -0
  316. package/dist/plugins/heading/locale/ru.js +10 -0
  317. package/dist/plugins/heading/mapTextFields.d.ts +1 -0
  318. package/dist/plugins/heading/mapTextFields.js +1 -0
  319. package/dist/plugins/image/README.md +93 -0
  320. package/dist/plugins/image/README.ru.md +94 -0
  321. package/dist/plugins/image/css.d.ts +47 -0
  322. package/dist/plugins/image/css.js +47 -0
  323. package/dist/plugins/image/icons.d.ts +13 -0
  324. package/dist/plugins/image/icons.js +26 -0
  325. package/dist/plugins/image/image.css +559 -0
  326. package/dist/plugins/image/index.d.ts +129 -0
  327. package/dist/plugins/image/index.js +346 -0
  328. package/dist/plugins/image/locale/en.d.ts +39 -0
  329. package/dist/plugins/image/locale/en.js +38 -0
  330. package/dist/plugins/image/locale/keys.d.ts +5 -0
  331. package/dist/plugins/image/locale/ru.d.ts +39 -0
  332. package/dist/plugins/image/locale/ru.js +38 -0
  333. package/dist/plugins/image/settings.d.ts +23 -0
  334. package/dist/plugins/image/settings.js +347 -0
  335. package/dist/plugins/image/state.d.ts +86 -0
  336. package/dist/plugins/image/state.js +151 -0
  337. package/dist/plugins/image/styles.d.ts +21 -0
  338. package/dist/plugins/image/styles.js +58 -0
  339. package/dist/plugins/image/uploader.d.ts +31 -0
  340. package/dist/plugins/image/uploader.js +92 -0
  341. package/dist/plugins/image/view-empty.d.ts +44 -0
  342. package/dist/plugins/image/view-empty.js +61 -0
  343. package/dist/plugins/image/view-filled.d.ts +49 -0
  344. package/dist/plugins/image/view-filled.js +282 -0
  345. package/dist/plugins/index.d.ts +21 -0
  346. package/dist/plugins/index.js +22 -0
  347. package/dist/plugins/link-preview/README.md +69 -0
  348. package/dist/plugins/link-preview/README.ru.md +70 -0
  349. package/dist/plugins/link-preview/index.d.ts +169 -0
  350. package/dist/plugins/link-preview/index.js +698 -0
  351. package/dist/plugins/link-preview/link-preview.css +254 -0
  352. package/dist/plugins/link-preview/locale/en.d.ts +14 -0
  353. package/dist/plugins/link-preview/locale/en.js +13 -0
  354. package/dist/plugins/link-preview/locale/keys.d.ts +5 -0
  355. package/dist/plugins/link-preview/locale/ru.d.ts +14 -0
  356. package/dist/plugins/link-preview/locale/ru.js +13 -0
  357. package/dist/plugins/list/README.md +59 -0
  358. package/dist/plugins/list/README.ru.md +60 -0
  359. package/dist/plugins/list/index.d.ts +134 -0
  360. package/dist/plugins/list/index.js +566 -0
  361. package/dist/plugins/list/list.css +57 -0
  362. package/dist/plugins/list/locale/en.d.ts +5 -0
  363. package/dist/plugins/list/locale/en.js +4 -0
  364. package/dist/plugins/list/locale/keys.d.ts +5 -0
  365. package/dist/plugins/list/locale/ru.d.ts +5 -0
  366. package/dist/plugins/list/locale/ru.js +4 -0
  367. package/dist/plugins/list/mapTextFields.d.ts +1 -0
  368. package/dist/plugins/list/mapTextFields.js +1 -0
  369. package/dist/plugins/paragraph/README.md +57 -0
  370. package/dist/plugins/paragraph/README.ru.md +58 -0
  371. package/dist/plugins/paragraph/index.d.ts +112 -0
  372. package/dist/plugins/paragraph/index.js +158 -0
  373. package/dist/plugins/paragraph/locale/en.d.ts +5 -0
  374. package/dist/plugins/paragraph/locale/en.js +4 -0
  375. package/dist/plugins/paragraph/locale/keys.d.ts +5 -0
  376. package/dist/plugins/paragraph/locale/ru.d.ts +5 -0
  377. package/dist/plugins/paragraph/locale/ru.js +4 -0
  378. package/dist/plugins/paragraph/mapTextFields.d.ts +1 -0
  379. package/dist/plugins/paragraph/mapTextFields.js +1 -0
  380. package/dist/plugins/paragraph/paragraph.css +56 -0
  381. package/dist/plugins/person/README.md +72 -0
  382. package/dist/plugins/person/README.ru.md +73 -0
  383. package/dist/plugins/person/index.d.ts +189 -0
  384. package/dist/plugins/person/index.js +777 -0
  385. package/dist/plugins/person/locale/en.d.ts +18 -0
  386. package/dist/plugins/person/locale/en.js +17 -0
  387. package/dist/plugins/person/locale/keys.d.ts +5 -0
  388. package/dist/plugins/person/locale/ru.d.ts +18 -0
  389. package/dist/plugins/person/locale/ru.js +17 -0
  390. package/dist/plugins/person/person.css +431 -0
  391. package/dist/plugins/person/socialResolver.d.ts +18 -0
  392. package/dist/plugins/person/socialResolver.js +69 -0
  393. package/dist/plugins/poll/README.md +96 -0
  394. package/dist/plugins/poll/README.ru.md +97 -0
  395. package/dist/plugins/poll/index.d.ts +134 -0
  396. package/dist/plugins/poll/index.js +825 -0
  397. package/dist/plugins/poll/locale/en.d.ts +23 -0
  398. package/dist/plugins/poll/locale/en.js +22 -0
  399. package/dist/plugins/poll/locale/keys.d.ts +5 -0
  400. package/dist/plugins/poll/locale/ru.d.ts +23 -0
  401. package/dist/plugins/poll/locale/ru.js +22 -0
  402. package/dist/plugins/poll/poll.css +400 -0
  403. package/dist/plugins/quote/README.md +55 -0
  404. package/dist/plugins/quote/README.ru.md +56 -0
  405. package/dist/plugins/quote/index.d.ts +81 -0
  406. package/dist/plugins/quote/index.js +165 -0
  407. package/dist/plugins/quote/locale/en.d.ts +6 -0
  408. package/dist/plugins/quote/locale/en.js +5 -0
  409. package/dist/plugins/quote/locale/keys.d.ts +5 -0
  410. package/dist/plugins/quote/locale/ru.d.ts +6 -0
  411. package/dist/plugins/quote/locale/ru.js +5 -0
  412. package/dist/plugins/quote/mapTextFields.d.ts +1 -0
  413. package/dist/plugins/quote/mapTextFields.js +1 -0
  414. package/dist/plugins/quote/quote.css +72 -0
  415. package/dist/plugins/raw/README.md +54 -0
  416. package/dist/plugins/raw/README.ru.md +55 -0
  417. package/dist/plugins/raw/index.d.ts +62 -0
  418. package/dist/plugins/raw/index.js +227 -0
  419. package/dist/plugins/raw/locale/en.d.ts +7 -0
  420. package/dist/plugins/raw/locale/en.js +6 -0
  421. package/dist/plugins/raw/locale/keys.d.ts +5 -0
  422. package/dist/plugins/raw/locale/ru.d.ts +7 -0
  423. package/dist/plugins/raw/locale/ru.js +6 -0
  424. package/dist/plugins/raw/raw.css +127 -0
  425. package/dist/plugins/shared/actionBar.d.ts +19 -0
  426. package/dist/plugins/shared/actionBar.js +35 -0
  427. package/dist/plugins/shared/dropzone.d.ts +106 -0
  428. package/dist/plugins/shared/dropzone.js +107 -0
  429. package/dist/plugins/shared/fileInput.d.ts +44 -0
  430. package/dist/plugins/shared/fileInput.js +62 -0
  431. package/dist/plugins/spoiler/README.md +55 -0
  432. package/dist/plugins/spoiler/README.ru.md +56 -0
  433. package/dist/plugins/spoiler/index.d.ts +61 -0
  434. package/dist/plugins/spoiler/index.js +169 -0
  435. package/dist/plugins/spoiler/locale/en.d.ts +7 -0
  436. package/dist/plugins/spoiler/locale/en.js +6 -0
  437. package/dist/plugins/spoiler/locale/keys.d.ts +5 -0
  438. package/dist/plugins/spoiler/locale/ru.d.ts +7 -0
  439. package/dist/plugins/spoiler/locale/ru.js +6 -0
  440. package/dist/plugins/spoiler/spoiler.css +101 -0
  441. package/dist/plugins/table/README.md +55 -0
  442. package/dist/plugins/table/README.ru.md +56 -0
  443. package/dist/plugins/table/index.d.ts +85 -0
  444. package/dist/plugins/table/index.js +399 -0
  445. package/dist/plugins/table/locale/en.d.ts +9 -0
  446. package/dist/plugins/table/locale/en.js +8 -0
  447. package/dist/plugins/table/locale/keys.d.ts +5 -0
  448. package/dist/plugins/table/locale/ru.d.ts +9 -0
  449. package/dist/plugins/table/locale/ru.js +8 -0
  450. package/dist/plugins/table/table.css +58 -0
  451. package/dist/plugins/toggle/README.md +56 -0
  452. package/dist/plugins/toggle/README.ru.md +57 -0
  453. package/dist/plugins/toggle/index.d.ts +69 -0
  454. package/dist/plugins/toggle/index.js +191 -0
  455. package/dist/plugins/toggle/locale/en.d.ts +7 -0
  456. package/dist/plugins/toggle/locale/en.js +6 -0
  457. package/dist/plugins/toggle/locale/keys.d.ts +5 -0
  458. package/dist/plugins/toggle/locale/ru.d.ts +7 -0
  459. package/dist/plugins/toggle/locale/ru.js +6 -0
  460. package/dist/plugins/toggle/toggle.css +101 -0
  461. package/dist/plugins/warning/README.md +55 -0
  462. package/dist/plugins/warning/README.ru.md +56 -0
  463. package/dist/plugins/warning/index.d.ts +66 -0
  464. package/dist/plugins/warning/index.js +167 -0
  465. package/dist/plugins/warning/locale/en.d.ts +6 -0
  466. package/dist/plugins/warning/locale/en.js +5 -0
  467. package/dist/plugins/warning/locale/keys.d.ts +5 -0
  468. package/dist/plugins/warning/locale/ru.d.ts +6 -0
  469. package/dist/plugins/warning/locale/ru.js +5 -0
  470. package/dist/plugins/warning/warning.css +63 -0
  471. package/dist/renderer/async.d.ts +1 -0
  472. package/dist/renderer/async.js +7 -0
  473. package/dist/renderer/errors.d.ts +27 -0
  474. package/dist/renderer/errors.js +48 -0
  475. package/dist/renderer/index.d.ts +82 -0
  476. package/dist/renderer/index.js +413 -0
  477. package/dist/renderer/inline.d.ts +5 -0
  478. package/dist/renderer/inline.js +61 -0
  479. package/dist/renderer/locale/en.d.ts +35 -0
  480. package/dist/renderer/locale/en.js +29 -0
  481. package/dist/renderer/locale/ru.d.ts +37 -0
  482. package/dist/renderer/locale/ru.js +29 -0
  483. package/dist/renderer/renderers/README.md +7 -0
  484. package/dist/renderer/renderers/README.ru.md +5 -0
  485. package/dist/renderer/renderers/async.d.ts +51 -0
  486. package/dist/renderer/renderers/async.js +99 -0
  487. package/dist/renderer/renderers/attaches/README.md +48 -0
  488. package/dist/renderer/renderers/attaches/README.ru.md +48 -0
  489. package/dist/renderer/renderers/attaches/index.d.ts +37 -0
  490. package/dist/renderer/renderers/attaches/index.js +451 -0
  491. package/dist/renderer/renderers/attaches/locale/en.d.ts +11 -0
  492. package/dist/renderer/renderers/attaches/locale/en.js +7 -0
  493. package/dist/renderer/renderers/attaches/locale/ru.d.ts +13 -0
  494. package/dist/renderer/renderers/attaches/locale/ru.js +7 -0
  495. package/dist/renderer/renderers/attaches/styles.css +196 -0
  496. package/dist/renderer/renderers/carousel/README.md +43 -0
  497. package/dist/renderer/renderers/carousel/README.ru.md +43 -0
  498. package/dist/renderer/renderers/carousel/index.d.ts +7 -0
  499. package/dist/renderer/renderers/carousel/index.js +110 -0
  500. package/dist/renderer/renderers/carousel/styles.css +7 -0
  501. package/dist/renderer/renderers/checklist/README.md +33 -0
  502. package/dist/renderer/renderers/checklist/README.ru.md +33 -0
  503. package/dist/renderer/renderers/checklist/index.d.ts +7 -0
  504. package/dist/renderer/renderers/checklist/index.js +55 -0
  505. package/dist/renderer/renderers/checklist/styles.css +54 -0
  506. package/dist/renderer/renderers/code/README.md +33 -0
  507. package/dist/renderer/renderers/code/README.ru.md +33 -0
  508. package/dist/renderer/renderers/code/index.d.ts +9 -0
  509. package/dist/renderer/renderers/code/index.js +137 -0
  510. package/dist/renderer/renderers/code/locale/en.d.ts +5 -0
  511. package/dist/renderer/renderers/code/locale/en.js +4 -0
  512. package/dist/renderer/renderers/code/locale/ru.d.ts +5 -0
  513. package/dist/renderer/renderers/code/locale/ru.js +4 -0
  514. package/dist/renderer/renderers/code/styles.css +330 -0
  515. package/dist/renderer/renderers/columns/README.md +33 -0
  516. package/dist/renderer/renderers/columns/README.ru.md +33 -0
  517. package/dist/renderer/renderers/columns/index.d.ts +7 -0
  518. package/dist/renderer/renderers/columns/index.js +53 -0
  519. package/dist/renderer/renderers/columns/styles.css +5 -0
  520. package/dist/renderer/renderers/delimiter/README.md +33 -0
  521. package/dist/renderer/renderers/delimiter/README.ru.md +33 -0
  522. package/dist/renderer/renderers/delimiter/index.d.ts +7 -0
  523. package/dist/renderer/renderers/delimiter/index.js +28 -0
  524. package/dist/renderer/renderers/delimiter/styles.css +12 -0
  525. package/dist/renderer/renderers/embed/README.md +35 -0
  526. package/dist/renderer/renderers/embed/README.ru.md +35 -0
  527. package/dist/renderer/renderers/embed/index.d.ts +8 -0
  528. package/dist/renderer/renderers/embed/index.js +66 -0
  529. package/dist/renderer/renderers/embed/styles.css +217 -0
  530. package/dist/renderer/renderers/gallery/README.md +41 -0
  531. package/dist/renderer/renderers/gallery/README.ru.md +41 -0
  532. package/dist/renderer/renderers/gallery/index.d.ts +8 -0
  533. package/dist/renderer/renderers/gallery/index.js +329 -0
  534. package/dist/renderer/renderers/gallery/styles.css +419 -0
  535. package/dist/renderer/renderers/heading/README.md +33 -0
  536. package/dist/renderer/renderers/heading/README.ru.md +33 -0
  537. package/dist/renderer/renderers/heading/index.d.ts +8 -0
  538. package/dist/renderer/renderers/heading/index.js +38 -0
  539. package/dist/renderer/renderers/heading/styles.css +26 -0
  540. package/dist/renderer/renderers/image/README.md +42 -0
  541. package/dist/renderer/renderers/image/README.ru.md +42 -0
  542. package/dist/renderer/renderers/image/index.d.ts +7 -0
  543. package/dist/renderer/renderers/image/index.js +93 -0
  544. package/dist/renderer/renderers/image/styles.css +40 -0
  545. package/dist/renderer/renderers/index.d.ts +47 -0
  546. package/dist/renderer/renderers/index.js +125 -0
  547. package/dist/renderer/renderers/link-preview/README.md +43 -0
  548. package/dist/renderer/renderers/link-preview/README.ru.md +43 -0
  549. package/dist/renderer/renderers/link-preview/index.d.ts +9 -0
  550. package/dist/renderer/renderers/link-preview/index.js +118 -0
  551. package/dist/renderer/renderers/link-preview/styles.css +246 -0
  552. package/dist/renderer/renderers/list/README.md +33 -0
  553. package/dist/renderer/renderers/list/README.ru.md +33 -0
  554. package/dist/renderer/renderers/list/index.d.ts +8 -0
  555. package/dist/renderer/renderers/list/index.js +42 -0
  556. package/dist/renderer/renderers/list/styles.css +20 -0
  557. package/dist/renderer/renderers/paragraph/README.md +33 -0
  558. package/dist/renderer/renderers/paragraph/README.ru.md +33 -0
  559. package/dist/renderer/renderers/paragraph/index.d.ts +7 -0
  560. package/dist/renderer/renderers/paragraph/index.js +35 -0
  561. package/dist/renderer/renderers/paragraph/styles.css +3 -0
  562. package/dist/renderer/renderers/person/README.md +44 -0
  563. package/dist/renderer/renderers/person/README.ru.md +44 -0
  564. package/dist/renderer/renderers/person/index.d.ts +7 -0
  565. package/dist/renderer/renderers/person/index.js +213 -0
  566. package/dist/renderer/renderers/person/locale/en.d.ts +6 -0
  567. package/dist/renderer/renderers/person/locale/en.js +5 -0
  568. package/dist/renderer/renderers/person/locale/ru.d.ts +6 -0
  569. package/dist/renderer/renderers/person/locale/ru.js +5 -0
  570. package/dist/renderer/renderers/person/styles.css +47 -0
  571. package/dist/renderer/renderers/poll/README.md +68 -0
  572. package/dist/renderer/renderers/poll/README.ru.md +68 -0
  573. package/dist/renderer/renderers/poll/index.d.ts +9 -0
  574. package/dist/renderer/renderers/poll/index.js +339 -0
  575. package/dist/renderer/renderers/poll/styles.css +148 -0
  576. package/dist/renderer/renderers/quote/README.md +33 -0
  577. package/dist/renderer/renderers/quote/README.ru.md +33 -0
  578. package/dist/renderer/renderers/quote/index.d.ts +7 -0
  579. package/dist/renderer/renderers/quote/index.js +59 -0
  580. package/dist/renderer/renderers/quote/styles.css +43 -0
  581. package/dist/renderer/renderers/raw/README.md +33 -0
  582. package/dist/renderer/renderers/raw/README.ru.md +33 -0
  583. package/dist/renderer/renderers/raw/index.d.ts +7 -0
  584. package/dist/renderer/renderers/raw/index.js +27 -0
  585. package/dist/renderer/renderers/spoiler/README.md +33 -0
  586. package/dist/renderer/renderers/spoiler/README.ru.md +33 -0
  587. package/dist/renderer/renderers/spoiler/index.d.ts +9 -0
  588. package/dist/renderer/renderers/spoiler/index.js +84 -0
  589. package/dist/renderer/renderers/spoiler/locale/en.d.ts +4 -0
  590. package/dist/renderer/renderers/spoiler/locale/en.js +3 -0
  591. package/dist/renderer/renderers/spoiler/locale/ru.d.ts +4 -0
  592. package/dist/renderer/renderers/spoiler/locale/ru.js +3 -0
  593. package/dist/renderer/renderers/spoiler/styles.css +61 -0
  594. package/dist/renderer/renderers/table/README.md +33 -0
  595. package/dist/renderer/renderers/table/README.ru.md +33 -0
  596. package/dist/renderer/renderers/table/index.d.ts +7 -0
  597. package/dist/renderer/renderers/table/index.js +83 -0
  598. package/dist/renderer/renderers/table/styles.css +34 -0
  599. package/dist/renderer/renderers/toggle/README.md +33 -0
  600. package/dist/renderer/renderers/toggle/README.ru.md +33 -0
  601. package/dist/renderer/renderers/toggle/index.d.ts +7 -0
  602. package/dist/renderer/renderers/toggle/index.js +59 -0
  603. package/dist/renderer/renderers/toggle/styles.css +49 -0
  604. package/dist/renderer/renderers/warning/README.md +33 -0
  605. package/dist/renderer/renderers/warning/README.ru.md +33 -0
  606. package/dist/renderer/renderers/warning/index.d.ts +7 -0
  607. package/dist/renderer/renderers/warning/index.js +62 -0
  608. package/dist/renderer/renderers/warning/styles.css +41 -0
  609. package/dist/renderer/styles/base.css +168 -0
  610. package/dist/renderer/types.d.ts +464 -0
  611. package/dist/shared/blockDataNormalizers.d.ts +14 -0
  612. package/dist/shared/blockDataNormalizers.js +235 -0
  613. package/dist/shared/blockDataValidators.d.ts +81 -0
  614. package/dist/shared/blockDataValidators.js +313 -0
  615. package/dist/shared/blockTypes.d.ts +2 -0
  616. package/dist/shared/blockTypes.js +26 -0
  617. package/dist/shared/carouselData.d.ts +34 -0
  618. package/dist/shared/carouselData.js +111 -0
  619. package/dist/shared/cloneEditorData.d.ts +11 -0
  620. package/dist/shared/cloneEditorData.js +20 -0
  621. package/dist/shared/documentTypes.d.ts +35 -0
  622. package/dist/shared/embedPlayer.d.ts +42 -0
  623. package/dist/shared/embedPlayer.js +141 -0
  624. package/dist/shared/fileUtils.d.ts +33 -0
  625. package/dist/shared/fileUtils.js +109 -0
  626. package/dist/shared/highlightRuntime.d.ts +38 -0
  627. package/dist/shared/highlightRuntime.js +75 -0
  628. package/dist/shared/inlineMarshal.d.ts +82 -0
  629. package/dist/shared/inlineMarshal.js +215 -0
  630. package/dist/shared/jsonData.d.ts +11 -0
  631. package/dist/shared/jsonData.js +53 -0
  632. package/dist/shared/localeTypes.d.ts +11 -0
  633. package/dist/shared/mapTextFields.d.ts +89 -0
  634. package/dist/shared/mapTextFields.js +119 -0
  635. package/dist/shared/pollData.d.ts +90 -0
  636. package/dist/shared/pollData.js +231 -0
  637. package/dist/shared/resolvePath.d.ts +8 -0
  638. package/dist/shared/resolvePath.js +10 -0
  639. package/dist/shared/runtime/dompurify.js +2424 -0
  640. package/dist/shared/runtime/highlightBundle.js +10 -0
  641. package/dist/shared/runtime/jszip.js +13 -0
  642. package/dist/shared/sanitize/allowlist.d.ts +21 -0
  643. package/dist/shared/sanitize/allowlist.js +40 -0
  644. package/dist/shared/sanitize/escapeHtml.d.ts +6 -0
  645. package/dist/shared/sanitize/escapeHtml.js +11 -0
  646. package/dist/shared/sanitize/index.d.ts +8 -0
  647. package/dist/shared/sanitize/index.js +8 -0
  648. package/dist/shared/sanitize/parseInline.d.ts +11 -0
  649. package/dist/shared/sanitize/parseInline.js +25 -0
  650. package/dist/shared/sanitize/sanitizeHtml.d.ts +8 -0
  651. package/dist/shared/sanitize/sanitizeHtml.js +19 -0
  652. package/dist/shared/sanitize/sanitizeRawHtml.d.ts +15 -0
  653. package/dist/shared/sanitize/sanitizeRawHtml.js +162 -0
  654. package/dist/shared/sanitize/sanitizeStyle.d.ts +9 -0
  655. package/dist/shared/sanitize/sanitizeStyle.js +39 -0
  656. package/dist/shared/sanitize/sanitizeUrl.d.ts +28 -0
  657. package/dist/shared/sanitize/sanitizeUrl.js +86 -0
  658. package/dist/shared/sanitize/walker.d.ts +15 -0
  659. package/dist/shared/sanitize/walker.js +98 -0
  660. package/dist/shared/styleRegistry.d.ts +4 -0
  661. package/dist/shared/styleRegistry.js +38 -0
  662. package/dist/shared/textFormat.d.ts +32 -0
  663. package/dist/shared/textFormat.js +48 -0
  664. package/dist/shared/zipRuntime.d.ts +19 -0
  665. package/dist/shared/zipRuntime.js +54 -0
  666. package/dist/styles/editor.css +3 -0
  667. package/dist/types.d.ts +1 -0
  668. package/package.json +149 -0
@@ -0,0 +1,198 @@
1
+ import { EditorEvent } from '../editorEvents.js'
2
+
3
+ /** @param {import('../types').IBlock} block */
4
+ function editableElement(block) {
5
+ const root = block.contentElement
6
+ if (root.matches('[contenteditable="true"]')) return root
7
+ return /** @type {HTMLElement | null} */ (root.querySelector('[contenteditable="true"]'))
8
+ }
9
+
10
+ /**
11
+ * Operations on cross-block selections (text spanning multiple blocks).
12
+ *
13
+ * Cross-block selection is held in `ICrossBlockSelection` (a custom range
14
+ * since the native browser API can't span editing hosts). This class
15
+ * encapsulates the multi-step delete sequence:
16
+ *
17
+ * 1. Delete tail of last block (from rangeEnd → end of CE).
18
+ * 2. Remove all middle blocks.
19
+ * 3. Delete head of first block (from start of CE → rangeStart).
20
+ * 4. Merge first + last (first block keeps the merged content).
21
+ * 5. Restore caret at the merge boundary.
22
+ *
23
+ * Wrapped in an UNDO_BATCH so the whole operation is one undo step.
24
+ */
25
+ export class CrossBlockEditor {
26
+ /** @type {HTMLElement} */
27
+ #rootEl
28
+
29
+ /** @type {import('../types').IBlockManager} */
30
+ #blocks
31
+
32
+ /** @type {import('../types').ISelectionManager} */
33
+ #selection
34
+
35
+ /** @type {import('../types').ICrossBlockSelection} */
36
+ #crossBlockSelection
37
+
38
+ /** @type {import('../types').IEventBus} */
39
+ #events
40
+
41
+ /** @type {string} */
42
+ #defaultBlockType
43
+
44
+ /**
45
+ * @param {HTMLElement} rootEl
46
+ * @param {import('../types').IBlockManager} blocks
47
+ * @param {import('../types').ISelectionManager} selection
48
+ * @param {import('../types').ICrossBlockSelection} crossBlockSelection
49
+ * @param {import('../types').IEventBus} events
50
+ * @param {string} defaultBlockType
51
+ */
52
+ constructor(rootEl, blocks, selection, crossBlockSelection, events, defaultBlockType) {
53
+ this.#rootEl = rootEl
54
+ this.#blocks = blocks
55
+ this.#selection = selection
56
+ this.#crossBlockSelection = crossBlockSelection
57
+ this.#events = events
58
+ this.#defaultBlockType = defaultBlockType
59
+ }
60
+
61
+ /**
62
+ * Place the native caret at the end of a cross-block range.
63
+ * Required so UndoManager captures the correct caret position when
64
+ * the next snapshot is taken.
65
+ *
66
+ * @param {Range} range
67
+ */
68
+ setCaretToRangeEnd(range) {
69
+ const endNode = range.endContainer
70
+ const endOffset = range.endOffset
71
+
72
+ const endBlock = this.#blocks.getBlockByChildNode(endNode)
73
+ if (!endBlock) return
74
+
75
+ const idx = this.#blocks.getBlockIndex(endBlock.id)
76
+ if (idx >= 0) this.#blocks.setCurrentIndex(idx)
77
+
78
+ endBlock.focus()
79
+
80
+ try {
81
+ const sel = window.getSelection()
82
+ const r = document.createRange()
83
+ r.setStart(endNode, endOffset)
84
+ r.collapse(true)
85
+ sel?.removeAllRanges()
86
+ sel?.addRange(r)
87
+ } catch {
88
+ // Range may be detached after a focus shift; ignore.
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Delete the content covered by a cross-block range and merge the
94
+ * surviving head + tail into the first block.
95
+ *
96
+ * @param {Range} crossRange
97
+ * @param {(...blocks: import('../types').IBlock[]) => void} notifyChanged
98
+ */
99
+ deleteContent(crossRange, notifyChanged) {
100
+ const blocks = this.#blocks
101
+
102
+ const firstBlock = blocks.getBlockByChildNode(crossRange.startContainer)
103
+ const lastBlock = blocks.getBlockByChildNode(crossRange.endContainer)
104
+ if (!firstBlock || !lastBlock || firstBlock === lastBlock) return
105
+
106
+ const firstIndex = blocks.getBlockIndex(firstBlock.id)
107
+ const lastIndex = blocks.getBlockIndex(lastBlock.id)
108
+ if (firstIndex < 0 || lastIndex <= firstIndex) return
109
+
110
+ const rangeStart = { node: crossRange.startContainer, offset: crossRange.startOffset }
111
+ const rangeEnd = { node: crossRange.endContainer, offset: crossRange.endOffset }
112
+
113
+ const firstCe = editableElement(firstBlock)
114
+ const lastCe = editableElement(lastBlock)
115
+
116
+ // The cross-block algorithm requires two editable endpoints. Validate
117
+ // before opening a history batch so malformed/detached ranges cannot
118
+ // leave UndoManager permanently batching.
119
+ if (!firstCe || !lastCe) return
120
+
121
+ this.#events.emit(EditorEvent.UNDO_BATCH_START)
122
+ try {
123
+ // 1. Delete tail of last block.
124
+ if (lastCe) {
125
+ try {
126
+ const delRange = document.createRange()
127
+ delRange.selectNodeContents(lastCe)
128
+ delRange.setEnd(rangeEnd.node, rangeEnd.offset)
129
+ delRange.deleteContents()
130
+ lastCe.normalize()
131
+ } catch {
132
+ // Range may have been invalidated mid-operation; ignore.
133
+ }
134
+ }
135
+
136
+ // 2. Remove middle blocks (skip first and last).
137
+ for (let index = lastIndex - 1; index > firstIndex; index--) {
138
+ blocks.remove(index)
139
+ }
140
+
141
+ // 3. Delete head of first block.
142
+ if (firstCe) {
143
+ try {
144
+ const delRange = document.createRange()
145
+ delRange.selectNodeContents(firstCe)
146
+ delRange.setStart(rangeStart.node, rangeStart.offset)
147
+ delRange.deleteContents()
148
+ firstCe.normalize()
149
+ } catch {
150
+ // ignore
151
+ }
152
+ }
153
+
154
+ // Caret target = end of remaining text in firstCe (the merge boundary).
155
+ const caretOffset = (firstCe?.textContent || '').length
156
+
157
+ // 4. Merge first + last.
158
+ if (lastCe !== firstCe) {
159
+ // Preserve boundary whitespace exactly. Trimming here joins words
160
+ // when a range ends immediately before a leading space in the tail.
161
+ const remaining = lastCe.innerHTML
162
+ if (remaining) {
163
+ const tpl = document.createElement('template')
164
+ tpl.innerHTML = remaining
165
+ firstCe.append(...tpl.content.childNodes)
166
+ }
167
+ const index = blocks.getBlockIndex(lastBlock.id)
168
+ if (index >= 0) blocks.remove(index)
169
+ }
170
+
171
+ blocks.clearSelection()
172
+ this.#crossBlockSelection.deactivate(this.#rootEl)
173
+
174
+ if (blocks.getBlockCount() === 0) blocks.insert(this.#defaultBlockType)
175
+
176
+ // 5. Restore caret at the merge boundary.
177
+ const focusIdx = blocks.getBlockIndex(firstBlock.id)
178
+ if (focusIdx >= 0) {
179
+ blocks.setCurrentIndex(focusIdx)
180
+ const block = blocks.getBlockByIndex(focusIdx)
181
+ if (block) {
182
+ block.focus()
183
+ if (caretOffset > 0) {
184
+ this.#selection.setCaretToOffset(block.id, caretOffset)
185
+ } else {
186
+ this.#selection.setCaretToBlock(block.id, 'start')
187
+ }
188
+ }
189
+ }
190
+
191
+ // Mark the surviving block dirty and notify while UndoManager is still
192
+ // batching, so the final snapshot observes the DOM mutation.
193
+ notifyChanged(firstBlock)
194
+ } finally {
195
+ this.#events.emit(EditorEvent.UNDO_BATCH_END)
196
+ }
197
+ }
198
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Routing table built from each plugin's `pasteConfig`.
3
+ *
4
+ * Three independent maps:
5
+ * - tag → plugin (for HTML element matching)
6
+ * - file MIME pattern → plugin (for `e.clipboardData.files`)
7
+ * - text regex → plugin (for plain-text URL/pattern matching)
8
+ *
9
+ * Built once at construction time, then queried by Clipboard during paste.
10
+ */
11
+ export class PasteRouter {
12
+ /** @param {Iterable<import('../types.js').BlockPlugin>} plugins */
13
+ constructor(plugins: Iterable<import("../types.js").BlockPlugin>);
14
+ /** @param {string} tag @returns {import('../types.js').BlockPlugin | undefined} */
15
+ findByTag(tag: string): import("../types.js").BlockPlugin | undefined;
16
+ /**
17
+ * @param {string} mime
18
+ * @returns {import('../types.js').BlockPlugin | undefined}
19
+ */
20
+ findByFile(mime: string): import("../types.js").BlockPlugin | undefined;
21
+ /**
22
+ * @param {string} text
23
+ * @returns {import('../types.js').BlockPlugin | undefined}
24
+ */
25
+ findByPattern(text: string): import("../types.js").BlockPlugin | undefined;
26
+ #private;
27
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Routing table built from each plugin's `pasteConfig`.
3
+ *
4
+ * Three independent maps:
5
+ * - tag → plugin (for HTML element matching)
6
+ * - file MIME pattern → plugin (for `e.clipboardData.files`)
7
+ * - text regex → plugin (for plain-text URL/pattern matching)
8
+ *
9
+ * Built once at construction time, then queried by Clipboard during paste.
10
+ */
11
+ export class PasteRouter {
12
+ /** @type {Map<string, import('../types').BlockPlugin>} */
13
+ #tagRoutes = new Map()
14
+
15
+ /** @type {Array<{ regex: RegExp, plugin: import('../types').BlockPlugin }>} */
16
+ #fileRoutes = []
17
+
18
+ /** @type {Array<{ regex: RegExp, plugin: import('../types').BlockPlugin }>} */
19
+ #patternRoutes = []
20
+
21
+ /** @param {Iterable<import('../types').BlockPlugin>} plugins */
22
+ constructor(plugins) {
23
+ for (const plugin of plugins) {
24
+ const config = plugin.pasteConfig
25
+ if (!config) continue
26
+
27
+ if (config.tags) {
28
+ for (const tag of config.tags) {
29
+ this.#tagRoutes.set(tag.toLowerCase(), plugin)
30
+ }
31
+ }
32
+
33
+ if (config.files) {
34
+ for (const mime of config.files) {
35
+ // Convert "image/*" → /^image\/.*$/i
36
+ const regex = new RegExp(
37
+ '^' + mime.replace(/[.+]/g, '\\$&').replace(/\*/g, '.*') + '$',
38
+ 'i',
39
+ )
40
+ this.#fileRoutes.push({ regex, plugin })
41
+ }
42
+ }
43
+
44
+ if (config.patterns) {
45
+ for (const pattern of config.patterns) {
46
+ this.#patternRoutes.push({ regex: pattern, plugin })
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ /** @param {string} tag @returns {import('../types').BlockPlugin | undefined} */
53
+ findByTag(tag) {
54
+ return this.#tagRoutes.get(tag.toLowerCase())
55
+ }
56
+
57
+ /**
58
+ * @param {string} mime
59
+ * @returns {import('../types').BlockPlugin | undefined}
60
+ */
61
+ findByFile(mime) {
62
+ return this.#fileRoutes.find((r) => r.regex.test(mime))?.plugin
63
+ }
64
+
65
+ /**
66
+ * @param {string} text
67
+ * @returns {import('../types').BlockPlugin | undefined}
68
+ */
69
+ findByPattern(text) {
70
+ return this.#patternRoutes.find((route) => this.#matches(route.regex, text))?.plugin
71
+ }
72
+
73
+ /**
74
+ * Plugin-owned expressions may be global or sticky. RegExp.test() mutates
75
+ * lastIndex for both flags, so every routing decision must start from the
76
+ * same state and leave the expression reusable by the next paste.
77
+ * @param {RegExp} regex
78
+ * @param {string} value
79
+ */
80
+ #matches(regex, value) {
81
+ regex.lastIndex = 0
82
+ const matched = regex.test(value)
83
+ regex.lastIndex = 0
84
+ return matched
85
+ }
86
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @typedef {Object} InsertContext
3
+ * @property {import('../types.js').IBlockManager} blocks
4
+ * @property {import('../types.js').ISelectionManager} selection
5
+ * @property {import('../BlockOperations.js').BlockOperations} blockOps
6
+ * @property {string} defaultBlockType
7
+ * @property {import('./PasteRouter.js').PasteRouter} router
8
+ * @property {(...blocks: import('../types.js').IBlock[]) => void} notifyChanged
9
+ */
10
+ /**
11
+ * Insert plain text into the editor at the current caret.
12
+ * Multi-line text becomes one block per non-empty line.
13
+ *
14
+ * @param {string} text
15
+ * @param {InsertContext} ctx
16
+ */
17
+ export function pastePlainText(text: string, ctx: InsertContext): void;
18
+ /**
19
+ * Insert HTML into the editor at the current caret.
20
+ * Splits multi-element HTML into multiple blocks via `extractBlockElements`,
21
+ * routes known tags to plugins via `pasteConfig.tags`, and falls back to
22
+ * the default block type for unknown tags.
23
+ *
24
+ * @param {string} html
25
+ * @param {InsertContext} ctx
26
+ */
27
+ export function pasteHtml(html: string, ctx: InsertContext): void;
28
+ export type InsertContext = {
29
+ blocks: import("../types.js").IBlockManager;
30
+ selection: import("../types.js").ISelectionManager;
31
+ blockOps: import("../BlockOperations.js").BlockOperations;
32
+ defaultBlockType: string;
33
+ router: import("./PasteRouter.js").PasteRouter;
34
+ notifyChanged: (...blocks: import("../types.js").IBlock[]) => void;
35
+ };
@@ -0,0 +1,215 @@
1
+ import { sanitizeHtml } from '../sanitize.js'
2
+ import { extractBlockElements } from './pasteUtils.js'
3
+
4
+ /**
5
+ * @typedef {Object} InsertContext
6
+ * @property {import('../types').IBlockManager} blocks
7
+ * @property {import('../types').ISelectionManager} selection
8
+ * @property {import('../BlockOperations').BlockOperations} blockOps
9
+ * @property {string} defaultBlockType
10
+ * @property {import('./PasteRouter.js').PasteRouter} router
11
+ * @property {(...blocks: import('../types').IBlock[]) => void} notifyChanged
12
+ */
13
+
14
+ /**
15
+ * Insert plain text into the editor at the current caret.
16
+ * Multi-line text becomes one block per non-empty line.
17
+ *
18
+ * @param {string} text
19
+ * @param {InsertContext} ctx
20
+ */
21
+ export function pastePlainText(text, ctx) {
22
+ const lines = text.split(/\n/)
23
+ const nonEmpty = lines.filter((line) => line.length > 0)
24
+ if (nonEmpty.length === 0) return
25
+ // Keep the original target before a multi-block paste moves current/focus
26
+ // to the last inserted block. This existing block is mutated directly and
27
+ // must be invalidated explicitly for the pre/post-paste history snapshots.
28
+ const targetBlock = ctx.blocks.getCurrentBlock()
29
+
30
+ if (nonEmpty.length === 1) {
31
+ insertTextOrReplace(/** @type {string} */ (nonEmpty[0]), ctx.blocks)
32
+ if (targetBlock) ctx.notifyChanged(targetBlock)
33
+ else ctx.notifyChanged()
34
+ return
35
+ }
36
+
37
+ insertTextOrReplace(/** @type {string} */ (nonEmpty[0]), ctx.blocks)
38
+
39
+ const currentIndex = ctx.blocks.getCurrentIndex()
40
+ let insertIndex = currentIndex + 1
41
+
42
+ for (let i = 1; i < nonEmpty.length; i++) {
43
+ const escaped = /** @type {string} */ (nonEmpty[i])
44
+ .replace(/&/g, '&amp;')
45
+ .replace(/</g, '&lt;')
46
+ .replace(/>/g, '&gt;')
47
+ ctx.blocks.insert(ctx.defaultBlockType, { text: escaped }, insertIndex)
48
+ insertIndex++
49
+ }
50
+
51
+ // Focus the last inserted block once (avoid intermediate focus shifts).
52
+ const lastBlock = ctx.blocks.getBlockByIndex(insertIndex - 1)
53
+ if (lastBlock) {
54
+ ctx.blocks.setCurrentIndex(insertIndex - 1)
55
+ ctx.selection.setCaretToBlock(lastBlock.id, 'end')
56
+ lastBlock.focus()
57
+ }
58
+
59
+ if (targetBlock) ctx.notifyChanged(targetBlock)
60
+ else ctx.notifyChanged()
61
+ }
62
+
63
+ /**
64
+ * Insert HTML into the editor at the current caret.
65
+ * Splits multi-element HTML into multiple blocks via `extractBlockElements`,
66
+ * routes known tags to plugins via `pasteConfig.tags`, and falls back to
67
+ * the default block type for unknown tags.
68
+ *
69
+ * @param {string} html
70
+ * @param {InsertContext} ctx
71
+ */
72
+ export function pasteHtml(html, ctx) {
73
+ // Parse clipboard markup in inert template content. Individual extracted
74
+ // blocks are sanitized before insertion or handed to an explicit plugin
75
+ // paste handler; no untrusted subtree is connected to the live document.
76
+ const template = document.createElement('template')
77
+ template.innerHTML = html
78
+
79
+ const extracted = extractBlockElements(
80
+ template.content,
81
+ (tag) => !!ctx.router.findByTag(tag),
82
+ )
83
+ // Routed non-text elements (for example IMG/HR) may have no textContent
84
+ // and still carry meaningful paste data in their attributes.
85
+ .filter((b) => (b.element.textContent || '').trim() || !!ctx.router.findByTag(b.tag))
86
+
87
+ if (extracted.length === 0) return
88
+
89
+ const first = /** @type {import('./pasteUtils.js').ExtractedBlock} */ (extracted[0])
90
+ const targetBlock = ctx.blocks.getCurrentBlock()
91
+
92
+ // Single paragraph → inline insert into the current block.
93
+ if (extracted.length === 1 && first.tag === 'p') {
94
+ const sanitized = sanitizeHtml(first.element.innerHTML)
95
+ if (sanitized) insertHtmlAtCaret(sanitized)
96
+ if (targetBlock) ctx.notifyChanged(targetBlock)
97
+ else ctx.notifyChanged()
98
+ return
99
+ }
100
+
101
+ const currentIndex = ctx.blocks.getCurrentIndex()
102
+ const currentBlock = ctx.blocks.getBlockByIndex(currentIndex)
103
+ const currentIsEmpty = currentBlock?.isEmpty()
104
+
105
+ const firstIsTextLike = first.tag === 'p' || first.tag === 'div'
106
+
107
+ if (firstIsTextLike) {
108
+ const sanitized = sanitizeHtml(first.element.innerHTML)
109
+ if (sanitized) {
110
+ if (currentIsEmpty && currentBlock) {
111
+ currentBlock.contentElement.innerHTML = sanitized
112
+ } else {
113
+ insertHtmlAtCaret(sanitized)
114
+ }
115
+ }
116
+ } else {
117
+ insertBlockFromExtracted(first, currentIndex + 1, ctx)
118
+ }
119
+
120
+ let insertIndex = currentIndex + 1
121
+ if (!firstIsTextLike) insertIndex++
122
+
123
+ for (let i = 1; i < extracted.length; i++) {
124
+ const item = /** @type {import('./pasteUtils.js').ExtractedBlock} */ (extracted[i])
125
+ insertBlockFromExtracted(item, insertIndex, ctx)
126
+ insertIndex++
127
+ }
128
+
129
+ if (extracted.length > 1 || first.tag !== 'p') {
130
+ const lastIdx = insertIndex - 1
131
+ const lastBlock = ctx.blocks.getBlockByIndex(lastIdx)
132
+ if (lastBlock) {
133
+ ctx.blocks.setCurrentIndex(lastIdx)
134
+ ctx.selection.setCaretToBlock(lastBlock.id, 'end')
135
+ lastBlock.focus()
136
+ }
137
+ }
138
+
139
+ if (firstIsTextLike && targetBlock) ctx.notifyChanged(targetBlock)
140
+ else ctx.notifyChanged()
141
+ }
142
+
143
+ /**
144
+ * @param {import('./pasteUtils.js').ExtractedBlock} extracted
145
+ * @param {number} index
146
+ * @param {InsertContext} ctx
147
+ */
148
+ function insertBlockFromExtracted(extracted, index, ctx) {
149
+ const plugin = ctx.router.findByTag(extracted.tag)
150
+
151
+ if (plugin?.onPaste) {
152
+ const data = plugin.onPaste({
153
+ type: 'tag',
154
+ element: extracted.element,
155
+ tag: extracted.tag,
156
+ })
157
+ if (data) {
158
+ ctx.blocks.insert(plugin.type, data, index)
159
+ return
160
+ }
161
+ }
162
+
163
+ const sanitized = sanitizeHtml(extracted.element.innerHTML)
164
+ ctx.blocks.insert(ctx.defaultBlockType, { text: sanitized }, index)
165
+ }
166
+
167
+ /**
168
+ * Insert text at the native caret. Falls back to overwriting the current
169
+ * block's content if no native selection exists.
170
+ *
171
+ * @param {string} text
172
+ * @param {import('../types').IBlockReader} blocks
173
+ */
174
+ function insertTextOrReplace(text, blocks) {
175
+ const sel = window.getSelection()
176
+ if (sel && sel.rangeCount > 0) {
177
+ insertTextAtCaret(text)
178
+ return
179
+ }
180
+ const block = blocks.getCurrentBlock()
181
+ if (block) block.contentElement.textContent = text
182
+ }
183
+
184
+ /** @param {string} text */
185
+ function insertTextAtCaret(text) {
186
+ const sel = window.getSelection()
187
+ if (!sel || sel.rangeCount === 0) return
188
+ const range = sel.getRangeAt(0)
189
+ range.deleteContents()
190
+ const textNode = document.createTextNode(text)
191
+ range.insertNode(textNode)
192
+ range.setStartAfter(textNode)
193
+ range.collapse(true)
194
+ sel.removeAllRanges()
195
+ sel.addRange(range)
196
+ }
197
+
198
+ /** @param {string} html */
199
+ function insertHtmlAtCaret(html) {
200
+ const sel = window.getSelection()
201
+ if (!sel || sel.rangeCount === 0) return
202
+ const range = sel.getRangeAt(0)
203
+ range.deleteContents()
204
+ const template = document.createElement('template')
205
+ template.innerHTML = html
206
+ const frag = template.content
207
+ const lastNode = frag.lastChild
208
+ range.insertNode(frag)
209
+ if (lastNode) {
210
+ range.setStartAfter(lastNode)
211
+ range.collapse(true)
212
+ sel.removeAllRanges()
213
+ sel.addRange(range)
214
+ }
215
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @typedef {Object} ExtractedBlock
3
+ * @property {string} tag Lowercase tag name (for example, `p`, `pre`, or `h2`).
4
+ * @property {HTMLElement} element Extracted DOM element.
5
+ */
6
+ /**
7
+ * Extract block-level elements from parsed HTML.
8
+ * Returns an array of {tag, element} objects for each block-level element found.
9
+ * Inline-only content is returned as a synthetic 'p' wrapper.
10
+ *
11
+ * @param {ParentNode} container Inert parsed HTML container.
12
+ * @param {(tag: string) => boolean} [isRoutedTag] Tests plugin-owned container tags.
13
+ * @returns {ExtractedBlock[]}
14
+ */
15
+ export function extractBlockElements(container: ParentNode, isRoutedTag?: (tag: string) => boolean): ExtractedBlock[];
16
+ export type ExtractedBlock = {
17
+ /**
18
+ * Lowercase tag name (for example, `p`, `pre`, or `h2`).
19
+ */
20
+ tag: string;
21
+ /**
22
+ * Extracted DOM element.
23
+ */
24
+ element: HTMLElement;
25
+ };
@@ -0,0 +1,98 @@
1
+ /** Block-level tags that represent separate paragraphs */
2
+ const BLOCK_TAGS = new Set([
3
+ 'p', 'div', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
4
+ 'blockquote', 'pre', 'tr', 'td', 'th', 'figure',
5
+ ])
6
+
7
+ /**
8
+ * Create a paragraph that remains owned by inert template content. Cloning
9
+ * untrusted media into a regular detached element can still start loading and
10
+ * fire event attributes before the paste sanitizer gets a chance to run.
11
+ * @returns {HTMLParagraphElement}
12
+ */
13
+ function createInertParagraph() {
14
+ const template = document.createElement('template')
15
+ template.innerHTML = '<p></p>'
16
+ return /** @type {HTMLParagraphElement} */ (template.content.firstElementChild)
17
+ }
18
+
19
+ /**
20
+ * @typedef {Object} ExtractedBlock
21
+ * @property {string} tag Lowercase tag name (for example, `p`, `pre`, or `h2`).
22
+ * @property {HTMLElement} element Extracted DOM element.
23
+ */
24
+
25
+ /**
26
+ * Extract block-level elements from parsed HTML.
27
+ * Returns an array of {tag, element} objects for each block-level element found.
28
+ * Inline-only content is returned as a synthetic 'p' wrapper.
29
+ *
30
+ * @param {ParentNode} container Inert parsed HTML container.
31
+ * @param {(tag: string) => boolean} [isRoutedTag] Tests plugin-owned container tags.
32
+ * @returns {ExtractedBlock[]}
33
+ */
34
+ export function extractBlockElements(container, isRoutedTag = () => false) {
35
+ /** @type {ExtractedBlock[]} */
36
+ const results = []
37
+ const isBlockTag = (tag) => BLOCK_TAGS.has(tag) || isRoutedTag(tag)
38
+
39
+ const hasBlockChild = Array.from(container.children).some(
40
+ c => isBlockTag(c.tagName.toLowerCase())
41
+ )
42
+
43
+ if (!hasBlockChild) {
44
+ // Wrap flat HTML without block structure as a single paragraph.
45
+ const p = createInertParagraph()
46
+ for (const child of container.childNodes) p.appendChild(child.cloneNode(true))
47
+ if (p.innerHTML.trim()) {
48
+ results.push({ tag: 'p', element: p })
49
+ }
50
+ return results
51
+ }
52
+
53
+ /**
54
+ * @param {import('../types').DOMNode} node
55
+ */
56
+ const walk = (node) => {
57
+ for (const child of node.childNodes) {
58
+ if (child.nodeType === Node.TEXT_NODE) {
59
+ const text = child.textContent?.trim()
60
+ if (text) {
61
+ const p = createInertParagraph()
62
+ p.textContent = text
63
+ results.push({ tag: 'p', element: p })
64
+ }
65
+ continue
66
+ }
67
+
68
+ if (child.nodeType !== Node.ELEMENT_NODE) continue
69
+
70
+ const el = /** @type {HTMLElement} */ (child)
71
+ const tag = el.tagName.toLowerCase()
72
+
73
+ if (tag === 'br') continue
74
+
75
+ if (isBlockTag(tag)) {
76
+ results.push({ tag, element: el })
77
+ } else {
78
+ // Inline or unknown — check for nested block children
79
+ const nested = Array.from(el.children).some(
80
+ c => isBlockTag(c.tagName.toLowerCase())
81
+ )
82
+
83
+ if (nested) {
84
+ walk(el)
85
+ } else {
86
+ const p = createInertParagraph()
87
+ for (const child of el.childNodes) p.appendChild(child.cloneNode(true))
88
+ if (p.innerHTML.trim()) {
89
+ results.push({ tag: 'p', element: p })
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ walk(container)
97
+ return results
98
+ }