@heartlandone/vega 2.102.0 → 2.103.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 (387) hide show
  1. package/dist/cjs/{app-globals-49c2a999.js → app-globals-85986306.js} +10 -10
  2. package/dist/cjs/{code-block-06e6591f.js → code-block-72de6c4d.js} +80 -1
  3. package/dist/cjs/{component-value-history-controller-slimmer.abstract-f29908f8.js → component-value-history-controller-slimmer.abstract-23d2b3d8.js} +3 -3
  4. package/dist/cjs/{content-state-8c862e5e.js → content-state-ff40bdc6.js} +38 -5
  5. package/dist/cjs/{date-required-rule-b672c432.js → date-required-rule-608e704b.js} +1 -1
  6. package/dist/cjs/{design-token-351ffd2c.js → design-token-a101a8d0.js} +3 -3
  7. package/dist/cjs/{element-appender-slimmer-f932b166.js → element-appender-slimmer-b93cc564.js} +2 -2
  8. package/dist/cjs/{form-field-controller-slimmer-5adb86ae.js → form-field-controller-slimmer-124d54ea.js} +1 -1
  9. package/dist/cjs/{image-annotation-action-25907d6b.js → image-annotation-action-1ee41bc7.js} +2 -2
  10. package/dist/cjs/{image-extension-1cf84f27.js → image-extension-6a92c524.js} +247 -5
  11. package/dist/cjs/index.cjs.js +17 -17
  12. package/dist/cjs/{inject-keyboard-manager-84d33920.js → inject-keyboard-manager-32d7dd0e.js} +1 -1
  13. package/dist/cjs/{internal-calendar-period-factory-3c5236be.js → internal-calendar-period-factory-c3198ea7.js} +1 -1
  14. package/dist/cjs/{internal-translation-controller-eae8a8de.js → internal-translation-controller-0d67ca4d.js} +1 -0
  15. package/dist/cjs/{keyboard-manager-baa83a61.js → keyboard-manager-332eec89.js} +1 -1
  16. package/dist/cjs/{keyboard-manager-slimmer-d1974b28.js → keyboard-manager-slimmer-a2872981.js} +1 -1
  17. package/dist/cjs/{link-extension-2a6133b7.js → link-extension-1b4ed437.js} +3 -3
  18. package/dist/cjs/loader.cjs.js +12 -12
  19. package/dist/cjs/{month-view-generator-a6827548.js → month-view-generator-b6a2b8be.js} +1 -1
  20. package/dist/cjs/{public-rules-7f26e0ae.js → public-rules-2066613c.js} +7 -7
  21. package/dist/cjs/{range-518b95a2.js → range-712fe703.js} +1 -1
  22. package/dist/cjs/{responsive-format-facade-95c54444.js → responsive-format-facade-44d33457.js} +1 -1
  23. package/dist/cjs/{rich-text-editor-required-rule-5d0c76ec.js → rich-text-editor-required-rule-1aa75d22.js} +1 -1
  24. package/dist/cjs/{split-cell-operation-28f6f8d9.js → split-cell-operation-afc82323.js} +3 -3
  25. package/dist/cjs/{state-border-formatter-6c284859.js → state-border-formatter-49984fd6.js} +1 -1
  26. package/dist/cjs/{string-format-strategy.abstract-f15b6196.js → string-format-strategy.abstract-bd563c01.js} +1 -1
  27. package/dist/cjs/{string-input-formatter-slimmer-5a3f1b55.js → string-input-formatter-slimmer-4faebac9.js} +1 -1
  28. package/dist/cjs/{string-mask-strategy-af6f3ba0.js → string-mask-strategy-624c4398.js} +2 -2
  29. package/dist/cjs/{style-formatter-324211fd.js → style-formatter-151d89a3.js} +2 -2
  30. package/dist/cjs/{time-required-rule-9e714442.js → time-required-rule-8cd8f9b9.js} +1 -1
  31. package/dist/cjs/{token-extension-86723cad.js → token-extension-72d0cb08.js} +1011 -767
  32. package/dist/cjs/{translation-slimmer-0227ee24.js → translation-slimmer-1771d01f.js} +1 -1
  33. package/dist/cjs/{type-guard-29e01bd4.js → type-guard-cce6fe1f.js} +1 -1
  34. package/dist/cjs/{valid-credit-card-number-rule-4ec364af.js → valid-credit-card-number-rule-b13c2fc4.js} +1 -1
  35. package/dist/cjs/vega-accordion.cjs.entry.js +6 -6
  36. package/dist/cjs/vega-app-header-button.cjs.entry.js +5 -5
  37. package/dist/cjs/vega-box.cjs.entry.js +6 -6
  38. package/dist/cjs/vega-button-circle.cjs.entry.js +5 -5
  39. package/dist/cjs/vega-button.cjs.entry.js +3 -3
  40. package/dist/cjs/vega-calendar_5.cjs.entry.js +7 -7
  41. package/dist/cjs/vega-card.cjs.entry.js +5 -5
  42. package/dist/cjs/vega-carousel.cjs.entry.js +3 -3
  43. package/dist/cjs/vega-checkbox_2.cjs.entry.js +2 -2
  44. package/dist/cjs/vega-chip.cjs.entry.js +5 -5
  45. package/dist/cjs/vega-code-block.cjs.entry.js +8 -8
  46. package/dist/cjs/vega-color-picker.cjs.entry.js +2 -2
  47. package/dist/cjs/vega-color-swatch-picker.cjs.entry.js +3 -3
  48. package/dist/cjs/vega-color-swatch.cjs.entry.js +2 -2
  49. package/dist/cjs/vega-combo-box.cjs.entry.js +8 -8
  50. package/dist/cjs/vega-date-picker_2.cjs.entry.js +13 -13
  51. package/dist/cjs/vega-dialog_2.cjs.entry.js +3 -3
  52. package/dist/cjs/vega-divider.cjs.entry.js +5 -5
  53. package/dist/cjs/vega-dropdown_5.cjs.entry.js +7 -7
  54. package/dist/cjs/vega-env-manager-23b8b23c.js +2 -2
  55. package/dist/cjs/vega-field-label.cjs.entry.js +2 -2
  56. package/dist/cjs/vega-file-uploader.cjs.entry.js +3 -3
  57. package/dist/cjs/vega-flag-icon.cjs.entry.js +5 -5
  58. package/dist/cjs/vega-flex.cjs.entry.js +6 -6
  59. package/dist/cjs/vega-font.cjs.entry.js +5 -5
  60. package/dist/cjs/vega-form.cjs.entry.js +2 -2
  61. package/dist/cjs/vega-grid.cjs.entry.js +5 -5
  62. package/dist/cjs/vega-icon.cjs.entry.js +5 -5
  63. package/dist/cjs/vega-image-uploader.cjs.entry.js +5 -5
  64. package/dist/cjs/vega-input-credit-card.cjs.entry.js +6 -6
  65. package/dist/cjs/vega-input-numeric.cjs.entry.js +12 -14
  66. package/dist/cjs/vega-input-passcode.cjs.entry.js +5 -5
  67. package/dist/cjs/vega-input-phone-number.cjs.entry.js +4 -4
  68. package/dist/cjs/vega-input-range.cjs.entry.js +3 -3
  69. package/dist/cjs/vega-input-select.cjs.entry.js +5 -5
  70. package/dist/cjs/vega-input.cjs.entry.js +31 -27
  71. package/dist/cjs/vega-left-nav_5.cjs.entry.js +7 -7
  72. package/dist/cjs/vega-loader-wrapper_2.cjs.entry.js +3 -3
  73. package/dist/cjs/vega-pagination-page-size-selector-mobile.cjs.entry.js +2 -2
  74. package/dist/cjs/vega-pagination.cjs.entry.js +4 -4
  75. package/dist/cjs/vega-popover_2.cjs.entry.js +8 -8
  76. package/dist/cjs/vega-progress-tracker_2.cjs.entry.js +3 -3
  77. package/dist/cjs/vega-radio_2.cjs.entry.js +5 -5
  78. package/dist/cjs/vega-rich-text-bookmark-editor.cjs.entry.js +2 -2
  79. package/dist/cjs/vega-rich-text-content.cjs.entry.js +6 -6
  80. package/dist/cjs/vega-rich-text-editor_4.cjs.entry.js +474 -207
  81. package/dist/cjs/vega-rich-text-find-replace-panel.cjs.entry.js +1 -1
  82. package/dist/cjs/vega-rich-text-special-characters-panel.cjs.entry.js +5 -5
  83. package/dist/cjs/vega-rich-text-table-properties_3.cjs.entry.js +8 -8
  84. package/dist/cjs/vega-selection-chip_2.cjs.entry.js +4 -4
  85. package/dist/cjs/vega-selection-tile_2.cjs.entry.js +2 -2
  86. package/dist/cjs/vega-sidenav_3.cjs.entry.js +3 -3
  87. package/dist/cjs/vega-signature-capture.cjs.entry.js +7 -7
  88. package/dist/cjs/vega-stepper.cjs.entry.js +2 -2
  89. package/dist/cjs/vega-tab-group_2.cjs.entry.js +6 -6
  90. package/dist/cjs/vega-table_11.cjs.entry.js +4 -4
  91. package/dist/cjs/vega-textarea.cjs.entry.js +2 -2
  92. package/dist/cjs/vega-time-picker_2.cjs.entry.js +9 -9
  93. package/dist/cjs/vega-toggle-switch.cjs.entry.js +2 -2
  94. package/dist/cjs/vega-tooltip_2.cjs.entry.js +6 -6
  95. package/dist/cjs/vega.cjs.js +12 -12
  96. package/dist/collection/components/vega-input/slimmers/controllers/vega-input-state-controller.js +0 -14
  97. package/dist/collection/components/vega-input/slimmers/renderers/vega-input-input-container-renderer.js +11 -2
  98. package/dist/collection/components/vega-input/slimmers/renderers/vega-input-input-renderer.js +11 -1
  99. package/dist/collection/components/vega-input/vega-input.js +52 -8
  100. package/dist/collection/components/vega-input-numeric/slimmers/renderers/vega-input-numeric-renderer.js +7 -1
  101. package/dist/collection/components/vega-input-numeric/vega-input-numeric.js +0 -8
  102. package/dist/collection/components/vega-rich-text-editor/constants/constant.js +4 -0
  103. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/sequential-composition-strategy.js +31 -0
  104. package/dist/collection/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.js +1 -0
  105. package/dist/collection/components/vega-rich-text-editor/dto/actions/sequential-composition-action.js +14 -0
  106. package/dist/collection/components/vega-rich-text-editor/dto/content-state.js +4 -1
  107. package/dist/collection/components/vega-rich-text-editor/dto/flush-changes-payload.js +1 -0
  108. package/dist/collection/components/vega-rich-text-editor/dto/nodes/image-node.js +3 -2
  109. package/dist/collection/components/vega-rich-text-editor/extensions/functions/dto/function-block.js +30 -0
  110. package/dist/collection/components/vega-rich-text-editor/extensions/functions/element-to-dto-strategies/div-to-function-block-strategy.js +1 -0
  111. package/dist/collection/components/vega-rich-text-editor/extensions/paste/controllers/chooser-positioner.js +107 -0
  112. package/dist/collection/components/vega-rich-text-editor/extensions/paste/controllers/paste-chooser-controller.js +91 -0
  113. package/dist/collection/components/vega-rich-text-editor/extensions/paste/controllers/paste-event-interceptor.js +47 -0
  114. package/dist/collection/components/vega-rich-text-editor/extensions/paste/controllers/selection-snapshot-service.js +54 -0
  115. package/dist/collection/components/vega-rich-text-editor/extensions/paste/parse-local-images-helper/image-extractor.js +17 -0
  116. package/dist/collection/components/vega-rich-text-editor/extensions/paste/paste-chooser-ui.js +3 -1
  117. package/dist/collection/components/vega-rich-text-editor/extensions/paste/paste-extension.js +41 -354
  118. package/dist/collection/components/vega-rich-text-editor/extensions/paste/pipeline/data-transfer-builder.js +36 -0
  119. package/dist/collection/components/vega-rich-text-editor/extensions/paste/pipeline/paste-dispatcher.js +23 -0
  120. package/dist/collection/components/vega-rich-text-editor/extensions/paste/pipeline/paste-processing-pipeline.js +30 -0
  121. package/dist/collection/components/vega-rich-text-editor/extensions/paste/strategies/paste-processing-strategy.abstract.js +34 -0
  122. package/dist/collection/components/vega-rich-text-editor/extensions/paste/strategies/paste-strategy-selector.js +19 -0
  123. package/dist/collection/components/vega-rich-text-editor/extensions/paste/strategies/plain-paste-strategy.js +74 -0
  124. package/dist/collection/components/vega-rich-text-editor/extensions/paste/type.js +1 -0
  125. package/dist/collection/components/vega-rich-text-editor/helpers/utils.js +67 -0
  126. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/abstract-delete-content-handler.js +67 -11
  127. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/backward-delete-content-handler.js +4 -17
  128. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/base-handler.js +34 -1
  129. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/forward-delete-content-handler.js +13 -32
  130. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/insert-line-break-handler.js +60 -25
  131. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/insert-paragraph-handler.js +55 -19
  132. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/insert-paste-handler.js +165 -59
  133. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/insert-text-handler.js +55 -21
  134. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/user-input-controller.js +2 -16
  135. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/value-controller.js +11 -1
  136. package/dist/collection/components/vega-rich-text-editor/utils/html-to-plain-text-utils.js +240 -0
  137. package/dist/collection/helpers/translation/locales/en.js +1 -0
  138. package/dist/esm/{app-globals-da5c83c2.js → app-globals-8cdfc5c9.js} +10 -10
  139. package/dist/esm/{code-block-d8f83d85.js → code-block-9360c331.js} +74 -2
  140. package/dist/esm/{component-value-history-controller-slimmer.abstract-642e7147.js → component-value-history-controller-slimmer.abstract-9ea58806.js} +3 -3
  141. package/dist/esm/{content-state-486eae1d.js → content-state-67a12e74.js} +38 -5
  142. package/dist/esm/{date-required-rule-08695d25.js → date-required-rule-66b5bf02.js} +1 -1
  143. package/dist/esm/{design-token-df3331d9.js → design-token-acd1efeb.js} +3 -3
  144. package/dist/esm/{element-appender-slimmer-f02a227f.js → element-appender-slimmer-7e5bc1e9.js} +2 -2
  145. package/dist/esm/{form-field-controller-slimmer-a7c0a0f8.js → form-field-controller-slimmer-d653c494.js} +1 -1
  146. package/dist/esm/{image-annotation-action-df744ba5.js → image-annotation-action-9525be48.js} +2 -2
  147. package/dist/esm/{image-extension-20b39140.js → image-extension-aea75132.js} +246 -6
  148. package/dist/esm/index.js +17 -17
  149. package/dist/esm/{inject-keyboard-manager-399ed867.js → inject-keyboard-manager-f6522d2f.js} +1 -1
  150. package/dist/esm/{internal-calendar-period-factory-7b866c3b.js → internal-calendar-period-factory-261df2f2.js} +1 -1
  151. package/dist/esm/{internal-translation-controller-4a7ee4d5.js → internal-translation-controller-3637e47e.js} +1 -0
  152. package/dist/esm/{keyboard-manager-f5d13a34.js → keyboard-manager-53e8d8d0.js} +1 -1
  153. package/dist/esm/{keyboard-manager-slimmer-f40dcb54.js → keyboard-manager-slimmer-b3de042d.js} +1 -1
  154. package/dist/esm/{link-extension-3f93d70d.js → link-extension-57ba9520.js} +3 -3
  155. package/dist/esm/loader.js +12 -12
  156. package/dist/esm/{month-view-generator-0c665987.js → month-view-generator-15215a09.js} +1 -1
  157. package/dist/esm/{public-rules-470a1dac.js → public-rules-c77a1550.js} +7 -7
  158. package/dist/esm/{range-8e89fb54.js → range-3c74e1c8.js} +1 -1
  159. package/dist/esm/{responsive-format-facade-55131a33.js → responsive-format-facade-1b325d06.js} +1 -1
  160. package/dist/esm/{rich-text-editor-required-rule-06caf383.js → rich-text-editor-required-rule-cfd32ba2.js} +1 -1
  161. package/dist/esm/{split-cell-operation-e158366a.js → split-cell-operation-85a036f9.js} +3 -3
  162. package/dist/esm/{state-border-formatter-2b73fa08.js → state-border-formatter-ce3495b0.js} +1 -1
  163. package/dist/esm/{string-format-strategy.abstract-8c7937e3.js → string-format-strategy.abstract-8ce04558.js} +1 -1
  164. package/dist/esm/{string-input-formatter-slimmer-681c6b71.js → string-input-formatter-slimmer-0d60ba7d.js} +1 -1
  165. package/dist/esm/{string-mask-strategy-b8cceee6.js → string-mask-strategy-cabc1d50.js} +2 -2
  166. package/dist/esm/{style-formatter-fcd70869.js → style-formatter-00fe4f1c.js} +2 -2
  167. package/dist/esm/{time-required-rule-ce50859b.js → time-required-rule-57ceeae9.js} +1 -1
  168. package/dist/esm/{token-extension-2401e753.js → token-extension-645a9520.js} +1011 -767
  169. package/dist/esm/{translation-slimmer-b3f3cf65.js → translation-slimmer-b69057eb.js} +1 -1
  170. package/dist/esm/{type-guard-08c82e08.js → type-guard-204094c6.js} +1 -1
  171. package/dist/esm/{valid-credit-card-number-rule-66bad519.js → valid-credit-card-number-rule-0874e19f.js} +1 -1
  172. package/dist/esm/vega-accordion.entry.js +6 -6
  173. package/dist/esm/vega-app-header-button.entry.js +5 -5
  174. package/dist/esm/vega-box.entry.js +6 -6
  175. package/dist/esm/vega-button-circle.entry.js +5 -5
  176. package/dist/esm/vega-button.entry.js +3 -3
  177. package/dist/esm/vega-calendar_5.entry.js +7 -7
  178. package/dist/esm/vega-card.entry.js +5 -5
  179. package/dist/esm/vega-carousel.entry.js +3 -3
  180. package/dist/esm/vega-checkbox_2.entry.js +2 -2
  181. package/dist/esm/vega-chip.entry.js +5 -5
  182. package/dist/esm/vega-code-block.entry.js +8 -8
  183. package/dist/esm/vega-color-picker.entry.js +2 -2
  184. package/dist/esm/vega-color-swatch-picker.entry.js +3 -3
  185. package/dist/esm/vega-color-swatch.entry.js +2 -2
  186. package/dist/esm/vega-combo-box.entry.js +8 -8
  187. package/dist/esm/vega-date-picker_2.entry.js +13 -13
  188. package/dist/esm/vega-dialog_2.entry.js +3 -3
  189. package/dist/esm/vega-divider.entry.js +5 -5
  190. package/dist/esm/vega-dropdown_5.entry.js +7 -7
  191. package/dist/esm/vega-env-manager-8f8dc473.js +2 -2
  192. package/dist/esm/vega-field-label.entry.js +2 -2
  193. package/dist/esm/vega-file-uploader.entry.js +3 -3
  194. package/dist/esm/vega-flag-icon.entry.js +5 -5
  195. package/dist/esm/vega-flex.entry.js +6 -6
  196. package/dist/esm/vega-font.entry.js +5 -5
  197. package/dist/esm/vega-form.entry.js +2 -2
  198. package/dist/esm/vega-grid.entry.js +5 -5
  199. package/dist/esm/vega-icon.entry.js +5 -5
  200. package/dist/esm/vega-image-uploader.entry.js +5 -5
  201. package/dist/esm/vega-input-credit-card.entry.js +6 -6
  202. package/dist/esm/vega-input-numeric.entry.js +12 -14
  203. package/dist/esm/vega-input-passcode.entry.js +5 -5
  204. package/dist/esm/vega-input-phone-number.entry.js +4 -4
  205. package/dist/esm/vega-input-range.entry.js +3 -3
  206. package/dist/esm/vega-input-select.entry.js +5 -5
  207. package/dist/esm/vega-input.entry.js +31 -27
  208. package/dist/esm/vega-left-nav_5.entry.js +7 -7
  209. package/dist/esm/vega-loader-wrapper_2.entry.js +3 -3
  210. package/dist/esm/vega-pagination-page-size-selector-mobile.entry.js +2 -2
  211. package/dist/esm/vega-pagination.entry.js +4 -4
  212. package/dist/esm/vega-popover_2.entry.js +8 -8
  213. package/dist/esm/vega-progress-tracker_2.entry.js +3 -3
  214. package/dist/esm/vega-radio_2.entry.js +5 -5
  215. package/dist/esm/vega-rich-text-bookmark-editor.entry.js +2 -2
  216. package/dist/esm/vega-rich-text-content.entry.js +6 -6
  217. package/dist/esm/vega-rich-text-editor_4.entry.js +474 -207
  218. package/dist/esm/vega-rich-text-find-replace-panel.entry.js +1 -1
  219. package/dist/esm/vega-rich-text-special-characters-panel.entry.js +5 -5
  220. package/dist/esm/vega-rich-text-table-properties_3.entry.js +8 -8
  221. package/dist/esm/vega-selection-chip_2.entry.js +4 -4
  222. package/dist/esm/vega-selection-tile_2.entry.js +2 -2
  223. package/dist/esm/vega-sidenav_3.entry.js +3 -3
  224. package/dist/esm/vega-signature-capture.entry.js +7 -7
  225. package/dist/esm/vega-stepper.entry.js +2 -2
  226. package/dist/esm/vega-tab-group_2.entry.js +6 -6
  227. package/dist/esm/vega-table_11.entry.js +4 -4
  228. package/dist/esm/vega-textarea.entry.js +2 -2
  229. package/dist/esm/vega-time-picker_2.entry.js +9 -9
  230. package/dist/esm/vega-toggle-switch.entry.js +2 -2
  231. package/dist/esm/vega-tooltip_2.entry.js +6 -6
  232. package/dist/esm/vega.js +12 -12
  233. package/dist/sri/vega-sri-manifest.json +321 -321
  234. package/dist/types/components/vega-input/slimmers/controllers/vega-input-state-controller.d.ts +0 -2
  235. package/dist/types/components/vega-input/slimmers/renderers/vega-input-input-container-renderer.d.ts +4 -0
  236. package/dist/types/components/vega-input/slimmers/renderers/vega-input-input-renderer.d.ts +2 -0
  237. package/dist/types/components/vega-input/vega-input.d.ts +15 -3
  238. package/dist/types/components/vega-input-numeric/slimmers/renderers/vega-input-numeric-renderer.d.ts +2 -0
  239. package/dist/types/components/vega-input-numeric/vega-input-numeric.d.ts +0 -2
  240. package/dist/types/components/vega-rich-text-editor/constants/constant.d.ts +4 -0
  241. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/sequential-composition-strategy.d.ts +14 -0
  242. package/dist/types/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.d.ts +4 -1
  243. package/dist/types/components/vega-rich-text-editor/dto/actions/sequential-composition-action.d.ts +30 -0
  244. package/dist/types/components/vega-rich-text-editor/dto/flush-changes-payload.d.ts +16 -0
  245. package/dist/types/components/vega-rich-text-editor/extensions/functions/dto/function-block.d.ts +7 -0
  246. package/dist/types/components/vega-rich-text-editor/extensions/paste/controllers/chooser-positioner.d.ts +33 -0
  247. package/dist/types/components/vega-rich-text-editor/extensions/paste/controllers/paste-chooser-controller.d.ts +43 -0
  248. package/dist/types/components/vega-rich-text-editor/extensions/paste/controllers/paste-event-interceptor.d.ts +22 -0
  249. package/dist/types/components/vega-rich-text-editor/extensions/paste/controllers/selection-snapshot-service.d.ts +29 -0
  250. package/dist/types/components/vega-rich-text-editor/extensions/paste/parse-local-images-helper/image-extractor.d.ts +13 -0
  251. package/dist/types/components/vega-rich-text-editor/extensions/paste/parse-local-images-helper/paste-image-parser.d.ts +1 -1
  252. package/dist/types/components/vega-rich-text-editor/extensions/paste/parse-local-images-helper/pending-image-registry.d.ts +1 -1
  253. package/dist/types/components/vega-rich-text-editor/extensions/paste/paste-chooser-ui.d.ts +1 -0
  254. package/dist/types/components/vega-rich-text-editor/extensions/paste/paste-extension.d.ts +28 -93
  255. package/dist/types/components/vega-rich-text-editor/extensions/paste/pipeline/data-transfer-builder.d.ts +10 -0
  256. package/dist/types/components/vega-rich-text-editor/extensions/paste/pipeline/paste-dispatcher.d.ts +8 -0
  257. package/dist/types/components/vega-rich-text-editor/extensions/paste/pipeline/paste-processing-pipeline.d.ts +18 -0
  258. package/dist/types/components/vega-rich-text-editor/extensions/paste/strategies/paste-processing-strategy.abstract.d.ts +28 -6
  259. package/dist/types/components/vega-rich-text-editor/extensions/paste/strategies/paste-strategy-selector.d.ts +13 -0
  260. package/dist/types/components/vega-rich-text-editor/extensions/paste/strategies/plain-paste-strategy.d.ts +29 -0
  261. package/dist/types/components/vega-rich-text-editor/extensions/paste/type.d.ts +35 -0
  262. package/dist/types/components/vega-rich-text-editor/helpers/utils.d.ts +47 -0
  263. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/abstract-delete-content-handler.d.ts +17 -6
  264. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/backward-delete-content-handler.d.ts +5 -1
  265. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/base-handler.d.ts +30 -1
  266. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/forward-delete-content-handler.d.ts +5 -1
  267. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/insert-line-break-handler.d.ts +21 -4
  268. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/insert-paragraph-handler.d.ts +12 -4
  269. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/insert-paste-handler.d.ts +38 -5
  270. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/insert-text-handler.d.ts +7 -2
  271. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/user-input-controller.d.ts +2 -0
  272. package/dist/types/components/vega-rich-text-editor/utils/html-to-plain-text-utils.d.ts +31 -0
  273. package/dist/types/components.d.ts +24 -0
  274. package/dist/types/helpers/translation/interface.d.ts +1 -0
  275. package/dist/types/types/public-api.d.ts +2 -1
  276. package/dist/vega/index.esm.js +1 -1
  277. package/dist/vega/{p-8a4cc7c2.entry.js → p-0169f71c.entry.js} +1 -1
  278. package/dist/vega/p-018bb83b.entry.js +1 -0
  279. package/dist/vega/{p-25e51acb.js → p-08bf08d2.js} +1 -1
  280. package/dist/vega/{p-85a940c0.entry.js → p-0b33753f.entry.js} +1 -1
  281. package/dist/vega/{p-a5fa260b.js → p-1537b1e4.js} +1 -1
  282. package/dist/vega/{p-7dfb1481.entry.js → p-17f6dc94.entry.js} +1 -1
  283. package/dist/vega/{p-dd673eb4.entry.js → p-1a4d1991.entry.js} +1 -1
  284. package/dist/vega/{p-557b64bd.js → p-1b2e5898.js} +1 -1
  285. package/dist/vega/{p-2256eb09.entry.js → p-1f1f93bf.entry.js} +1 -1
  286. package/dist/vega/{p-d86e0b01.js → p-1fb953f8.js} +1 -1
  287. package/dist/vega/{p-03efc67a.entry.js → p-2171b571.entry.js} +1 -1
  288. package/dist/vega/p-255fe20b.js +1 -0
  289. package/dist/vega/{p-cf5c5515.js → p-261cf764.js} +1 -1
  290. package/dist/vega/{p-f0b49ae4.entry.js → p-27e77ea1.entry.js} +1 -1
  291. package/dist/vega/{p-109f0e33.entry.js → p-28acbe42.entry.js} +1 -1
  292. package/dist/vega/{p-27c9c2a5.entry.js → p-2acc600a.entry.js} +1 -1
  293. package/dist/vega/p-2fc2299f.js +1 -0
  294. package/dist/vega/{p-b48caf90.entry.js → p-2ff659a1.entry.js} +1 -1
  295. package/dist/vega/{p-527c3211.entry.js → p-322da1eb.entry.js} +1 -1
  296. package/dist/vega/{p-dffe47db.js → p-3283fa2f.js} +1 -1
  297. package/dist/vega/p-3567dc55.entry.js +1 -0
  298. package/dist/vega/{p-c6419eb3.entry.js → p-36b795c6.entry.js} +1 -1
  299. package/dist/vega/p-37714a3a.js +1 -0
  300. package/dist/vega/{p-d7e59f31.js → p-3b4e2ba0.js} +1 -1
  301. package/dist/vega/{p-3d060d2f.entry.js → p-3b911043.entry.js} +1 -1
  302. package/dist/vega/{p-5c6d36ef.entry.js → p-3e270b65.entry.js} +1 -1
  303. package/dist/vega/{p-b68f55e2.js → p-4043508a.js} +1 -1
  304. package/dist/vega/p-4151d4a8.js +1 -0
  305. package/dist/vega/{p-c6b6987e.js → p-45af801f.js} +1 -1
  306. package/dist/vega/p-48c2150b.entry.js +1 -0
  307. package/dist/vega/p-4b253f74.entry.js +1 -0
  308. package/dist/vega/{p-75c7f8ea.entry.js → p-4cdc064d.entry.js} +1 -1
  309. package/dist/vega/{p-1d8a8507.entry.js → p-4e4b50f3.entry.js} +1 -1
  310. package/dist/vega/{p-d8fa2f19.entry.js → p-564110ba.entry.js} +1 -1
  311. package/dist/vega/p-5f377954.js +1 -1
  312. package/dist/vega/{p-bec31ffc.entry.js → p-608d3559.entry.js} +1 -1
  313. package/dist/vega/{p-3ce7521e.entry.js → p-64eb05d3.entry.js} +1 -1
  314. package/dist/vega/{p-2f5c4b61.entry.js → p-66bf209b.entry.js} +1 -1
  315. package/dist/vega/{p-83f5ef3a.entry.js → p-69eadbd8.entry.js} +1 -1
  316. package/dist/vega/{p-c66c6fd2.entry.js → p-6c4edee8.entry.js} +1 -1
  317. package/dist/vega/p-6e16bb3a.js +1 -0
  318. package/dist/vega/{p-7d748545.entry.js → p-76f4fdba.entry.js} +1 -1
  319. package/dist/vega/{p-4c6989ae.entry.js → p-7874055b.entry.js} +1 -1
  320. package/dist/vega/{p-ca60a74b.entry.js → p-7d3d24f6.entry.js} +1 -1
  321. package/dist/vega/{p-3bfb53e3.js → p-7f9ad7bc.js} +1 -1
  322. package/dist/vega/{p-18ddc6a4.entry.js → p-8193f4ef.entry.js} +1 -1
  323. package/dist/vega/{p-816064f2.entry.js → p-8197d172.entry.js} +1 -1
  324. package/dist/vega/{p-634b138c.entry.js → p-8ac0b1b2.entry.js} +1 -1
  325. package/dist/vega/{p-553510d8.entry.js → p-8c61db9d.entry.js} +1 -1
  326. package/dist/vega/{p-061a76c3.entry.js → p-8de29082.entry.js} +1 -1
  327. package/dist/vega/{p-325b804d.entry.js → p-8e59606f.entry.js} +1 -1
  328. package/dist/vega/p-8ea41806.js +1 -0
  329. package/dist/vega/{p-ff9090af.entry.js → p-9153c2f5.entry.js} +1 -1
  330. package/dist/vega/{p-a0c87e88.entry.js → p-92411f56.entry.js} +1 -1
  331. package/dist/vega/{p-049e64b1.entry.js → p-94d65dcf.entry.js} +1 -1
  332. package/dist/vega/{p-a261a675.entry.js → p-9a96fb05.entry.js} +1 -1
  333. package/dist/vega/{p-7044bb48.js → p-9fcfd738.js} +1 -1
  334. package/dist/vega/{p-b1e1c7d0.js → p-a2c7a3bc.js} +1 -1
  335. package/dist/vega/p-a2dcde12.js +1 -0
  336. package/dist/vega/{p-be0eb72f.js → p-a60d75d9.js} +1 -1
  337. package/dist/vega/{p-5a347a15.js → p-a9fc4043.js} +1 -1
  338. package/dist/vega/{p-efef0dfe.entry.js → p-abe5f7f0.entry.js} +1 -1
  339. package/dist/vega/{p-197388a5.entry.js → p-ac98c189.entry.js} +1 -1
  340. package/dist/vega/{p-dd273d89.entry.js → p-ade903b3.entry.js} +1 -1
  341. package/dist/vega/{p-c0eb8c58.js → p-affb40e8.js} +1 -1
  342. package/dist/vega/{p-277aab9b.js → p-b3a1cd22.js} +1 -1
  343. package/dist/vega/p-b63a90b3.entry.js +1 -0
  344. package/dist/vega/{p-f9f96030.entry.js → p-ba050d63.entry.js} +1 -1
  345. package/dist/vega/{p-bf0b46c1.js → p-ba67eb96.js} +1 -1
  346. package/dist/vega/{p-f0c6e9c5.entry.js → p-c08ac33f.entry.js} +1 -1
  347. package/dist/vega/{p-46be74fc.entry.js → p-c7ec97d1.entry.js} +1 -1
  348. package/dist/vega/{p-effbfc50.entry.js → p-ca1fe571.entry.js} +1 -1
  349. package/dist/vega/{p-408c3ad4.entry.js → p-cc9fc36a.entry.js} +1 -1
  350. package/dist/vega/{p-741e064e.entry.js → p-d044d54f.entry.js} +1 -1
  351. package/dist/vega/{p-0e0e66c9.entry.js → p-d3a9355c.entry.js} +1 -1
  352. package/dist/vega/p-d5a75228.js +1 -0
  353. package/dist/vega/{p-76135e80.entry.js → p-dc83fa6b.entry.js} +1 -1
  354. package/dist/vega/{p-92efdbf0.entry.js → p-dcfce26e.entry.js} +1 -1
  355. package/dist/vega/p-df9585f6.js +3 -0
  356. package/dist/vega/{p-f5f26b44.entry.js → p-e2c8a470.entry.js} +1 -1
  357. package/dist/vega/{p-23781e76.js → p-e33a954f.js} +1 -1
  358. package/dist/vega/{p-e577dda8.entry.js → p-e5fc6583.entry.js} +1 -1
  359. package/dist/vega/p-e668cf11.js +1 -0
  360. package/dist/vega/{p-0338f621.entry.js → p-e6b0a292.entry.js} +1 -1
  361. package/dist/vega/{p-381d8781.js → p-e84c2589.js} +1 -1
  362. package/dist/vega/{p-1b97e751.entry.js → p-eb945d34.entry.js} +1 -1
  363. package/dist/vega/{p-d8a0e3e0.entry.js → p-ebe1dd2b.entry.js} +1 -1
  364. package/dist/vega/{p-6beaf1c8.entry.js → p-f818bb20.entry.js} +1 -1
  365. package/dist/vega/p-f981cf2c.js +1 -0
  366. package/dist/vega/p-f9d09b0c.js +1 -0
  367. package/dist/vega/{p-4d20a56f.js → p-fdbdf12f.js} +1 -1
  368. package/dist/vega/{p-48100d38.entry.js → p-fee080b9.entry.js} +1 -1
  369. package/dist/vega/vega.esm.js +1 -1
  370. package/package.json +1 -1
  371. package/dist/vega/p-040bd9ca.js +0 -1
  372. package/dist/vega/p-087240db.js +0 -1
  373. package/dist/vega/p-15052b2e.entry.js +0 -1
  374. package/dist/vega/p-28c16885.js +0 -1
  375. package/dist/vega/p-30cc31dd.entry.js +0 -1
  376. package/dist/vega/p-3ec4d710.js +0 -1
  377. package/dist/vega/p-43ea1e86.js +0 -1
  378. package/dist/vega/p-7228088b.entry.js +0 -1
  379. package/dist/vega/p-7f711049.js +0 -1
  380. package/dist/vega/p-7fd15dd1.js +0 -1
  381. package/dist/vega/p-85695819.js +0 -1
  382. package/dist/vega/p-8e1f30ec.entry.js +0 -1
  383. package/dist/vega/p-9680dfe6.js +0 -1
  384. package/dist/vega/p-ae12cc3f.js +0 -3
  385. package/dist/vega/p-c0823f32.js +0 -1
  386. package/dist/vega/p-c5af2ecc.entry.js +0 -1
  387. package/dist/vega/p-fa43272c.js +0 -1
@@ -7,28 +7,28 @@ import { C as ChangeManager } from './change-manager-6a7eb88c.js';
7
7
  import { d as domNodeSubjectFactory, D as DomNodeSubjectObserverFactory } from './dom-node-subject-observer-factory-bb7e68a0.js';
8
8
  import { s as VegaInternalComponentDidRender, e as VegaInternalRichTextEditorFlushChanges, d as VegaInternalRichTextEditDeleteSelectedNodes, G as VegaInternalRichTextImageClick, H as VegaInternalRichTextImageDeleteButtonClicked, y as VegaInternalCodeBlockBlur, a as VegaInternalPopoverUpdateTarget } from './vega-internal-event-id-02093067.js';
9
9
  import { S as SHADOW_ROOT_ELEMENT_SCROLLING, F as FORM_ELEMENT_VALUE_CHANGE } from './static-subject-title-1c86e974.js';
10
- import { ak as ZERO_WIDTH_SPACE, ap as VegaRTEOneRowHeightPx, R as RTETextNode, ae as BoldAnnotationAction, N as NodeAnnotationTypeEnum, aq as ItalicAnnotationAction, ar as UnderlineAnnotationAction, b as RTETextBlock, as as TextStyleAnnotationAction, a2 as TextStyleAnnotation, at as BoldAnnotation, au as BlockAnnotationTypeEnum, av as ClearFormattingAnnotationAction, aw as CodeAnnotationAction, ax as StrikethroughAnnotationAction, an as SelectionChangeAction, al as LinkAnnotationAction, ay as IndentAnnotationAction, M as ModifyContentAction, j as ModifyContentActionType, r as RTEListItemBlock, a3 as RTEHtmlBlock, az as TransformParagraphAction, t as RTECodeBlockNode, A as ActionHandleStrategyRegistry, J as HorizontalAlignmentAnnotationAction, aA as RTEUpdateSource, s as stateEntityRenderingRegistry, f as AppendChildrenAction, U as UpdateTextAction, h as InsertChildrenBeforeAction, S as SplitBlockWithNodeAction, g as RTENode, a as RTEBlock, l as RemoveChildrenAction, E as ReplaceChildNodesAction, aB as escapeHtml, w as RTE_PASTE_MODE_DATA_TYPE, aC as RTE_PASTE_MODE_WORD, q as RTECodeBlock, aD as RTE_UPDATE_SOURCE_KEY, I as InsertChildrenAfterAction, x as RTE_WORD_COUNT_KEY, V as VegaRTEPresetToolbarItems, aj as VegaRTEDefaultTextStyleItems, aE as RTE_EMAIL_LINK_TYPE_KEY, aF as RTE_DEFAULT_LINK_TYPE_KEY, aG as RTE_SUPPORTED_LINK_TYPE_KEYS } from './code-block-d8f83d85.js';
11
- import { i as isNonNullable } from './type-guard-08c82e08.js';
12
- import { R as RTEDTORendererManager, e as extensionContextManager, V as VegaRTELinkExtension } from './link-extension-3f93d70d.js';
10
+ import { ar as ZERO_WIDTH_SPACE, aw as VegaRTEOneRowHeightPx, R as RTETextNode, ai as BoldAnnotationAction, N as NodeAnnotationTypeEnum, ax as ItalicAnnotationAction, ay as UnderlineAnnotationAction, c as RTETextBlock, az as TextStyleAnnotationAction, a6 as TextStyleAnnotation, aA as BoldAnnotation, aB as BlockAnnotationTypeEnum, aC as ClearFormattingAnnotationAction, aD as CodeAnnotationAction, aE as StrikethroughAnnotationAction, au as SelectionChangeAction, as as LinkAnnotationAction, aF as IndentAnnotationAction, M as ModifyContentAction, j as ModifyContentActionType, r as RTEListItemBlock, a7 as RTEHtmlBlock, aG as TransformParagraphAction, t as RTECodeBlockNode, A as ActionHandleStrategyRegistry, P as HorizontalAlignmentAnnotationAction, aH as RTEUpdateSource, s as stateEntityRenderingRegistry, g as AppendChildrenAction, aI as RTE_UPDATE_SOURCE_KEY, U as UpdateTextAction, h as InsertChildrenBeforeAction, S as SplitBlockWithNodeAction, a as RTENode, b as RTEBlock, l as RemoveChildrenAction, K as ReplaceChildNodesAction, aJ as RTE_PASTE_MODE_PLAIN, ak as normalizePlainTextLines, x as toPlainPasteLines, J as escapeHtml, z as RTE_PASTE_MODE_DATA_TYPE, y as RTE_PRESERVED_WHITESPACE_DATA_TYPE, aK as RTE_PASTE_MODE_WORD, q as RTECodeBlock, I as InsertChildrenAfterAction, D as RTE_WORD_COUNT_KEY, V as VegaRTEPresetToolbarItems, aq as VegaRTEDefaultTextStyleItems, aL as RTE_EMAIL_LINK_TYPE_KEY, aM as RTE_DEFAULT_LINK_TYPE_KEY, aN as RTE_SUPPORTED_LINK_TYPE_KEYS } from './code-block-9360c331.js';
11
+ import { i as isNonNullable } from './type-guard-204094c6.js';
12
+ import { R as RTEDTORendererManager, e as extensionContextManager, V as VegaRTELinkExtension } from './link-extension-57ba9520.js';
13
13
  import { V as VegaInternalIconManager } from './internal-icon-manager-d4d534d2.js';
14
- import { V as VisualModeToolbarButtonSlimmer, I as ImageAnnotationAction, a as ToolbarButtonSlimmer, T as TextColorToolbarButtonSlimmer, n as normalizeUrlByDefaultProtocol } from './image-annotation-action-df744ba5.js';
14
+ import { V as VisualModeToolbarButtonSlimmer, I as ImageAnnotationAction, a as ToolbarButtonSlimmer, T as TextColorToolbarButtonSlimmer, n as normalizeUrlByDefaultProtocol } from './image-annotation-action-9525be48.js';
15
15
  import { d as VegaDropdownClick, c as VegaChange, b as VegaClick, a2 as VegaImageInserted, a3 as VegaSourceCodeChange, a as VegaPopoverShow, V as VegaPopoverHide, T as VegaShow, U as VegaHide } from './vega-event-id-6b4db259.js';
16
16
  import { g as generateUUID } from './misc-9fdbcfbb.js';
17
17
  import { w as waitForComponentDidRender } from './wait-for-component-did-render-9e84d92d.js';
18
- import { a as VegaRTEImageExtension, R as ReplaceSelectedTextAction, c as bookmarkIcon, d as collectBookmarkNames, V as VegaRTEBookmarkExtension } from './image-extension-20b39140.js';
19
- import { F as FormFieldControllerSlimmer } from './form-field-controller-slimmer-a7c0a0f8.js';
18
+ import { a as VegaRTEImageExtension, R as ReplaceSelectedTextAction, h as htmlContainsTable, c as htmlToPlainText, d as bookmarkIcon, e as collectBookmarkNames, V as VegaRTEBookmarkExtension } from './image-extension-aea75132.js';
19
+ import { F as FormFieldControllerSlimmer } from './form-field-controller-slimmer-d653c494.js';
20
20
  import { c as createEventEmitSlimmer } from './event-emit-slimmer-aa7f4c6e.js';
21
21
  import { c as createSubStateNotifySlimmer } from './sub-state-notify-slimmer-ba72f30b.js';
22
- import { V as VegaRTEContent, b as RTEImageNode, f as CommitValueAction, M as MergeTwoBlocksNodesAction, I as InsertNewParagraphAction, S as StylePreservator, g as ElementToDtoStrategyProcessor, R as RTEImageBlock } from './content-state-486eae1d.js';
22
+ import { V as VegaRTEContent, b as RTEImageNode, f as CommitValueAction, U as UpdateCursorPositionAction, M as MergeTwoBlocksNodesAction, I as InsertNewParagraphAction, S as StylePreservator, g as ElementToDtoStrategyProcessor, R as RTEImageBlock } from './content-state-67a12e74.js';
23
23
  import { b as AlignLeft, A as AlignCenter, c as AlignRight, a as AlignJustify } from './align-left-7f959adf.js';
24
- import { R as RTESelectionState, C as ComponentValueHistoryControllerSlimmer, a as SelectionController } from './component-value-history-controller-slimmer.abstract-642e7147.js';
24
+ import { R as RTESelectionState, C as ComponentValueHistoryControllerSlimmer, a as SelectionController } from './component-value-history-controller-slimmer.abstract-9ea58806.js';
25
25
  import { O as Observer } from './observer-3959f9dd.js';
26
26
  import { d as debounce } from './timer-9321173b.js';
27
27
  import { D as DarkModeStateControllerSlimmer } from './dark-mode-state-controller-slimmer-778dd929.js';
28
28
  import { f as findParent, b as getDeepActiveElementInShadow, j as checkIsVoiceOverClick, k as getFirstFocusableElement } from './ui-80e610f4.js';
29
- import { R as RichTextEditorRequiredRule } from './rich-text-editor-required-rule-06caf383.js';
29
+ import { R as RichTextEditorRequiredRule } from './rich-text-editor-required-rule-cfd32ba2.js';
30
30
  import { C as ChildNodesEventPreventSlimmer } from './child-nodes-event-prevent-slimmer-3ae5c7db.js';
31
- import { T as TranslationSlimmer } from './translation-slimmer-b3f3cf65.js';
31
+ import { T as TranslationSlimmer } from './translation-slimmer-b69057eb.js';
32
32
  import { V as VegaInternalThemeManager } from './dark-mode-style-controller-4e04a2d3.js';
33
33
  import { A as AutoRunWhenReRenderTaskQueueSlimmer } from './auto-run-when-re-render-task-queue-slimmer.abstract-27820d4c.js';
34
34
  import { i as isArrayEqual } from './array-7888f339.js';
@@ -44,7 +44,7 @@ import './discriminated-fe5bf3c8.js';
44
44
  import './dynamic-slimmer-90b8af32.js';
45
45
  import './breakpoints-d9faf11c.js';
46
46
  import './ui-93922c59.js';
47
- import './internal-translation-controller-4a7ee4d5.js';
47
+ import './internal-translation-controller-3637e47e.js';
48
48
  import './icon-manager-236d6c23.js';
49
49
  import './try-get-document-bef0f526.js';
50
50
  import './vega-nonce-manager-497e5eb5.js';
@@ -57,9 +57,9 @@ import './mutation-observer-slimmer-58ebc13c.js';
57
57
  import './mutation-observer-filters-1a054fb0.js';
58
58
  import './sub-state-observer-slimmer-bee1c7fa.js';
59
59
  import './internal-vega-event-manager-6eebe8f8.js';
60
- import './range-8e89fb54.js';
61
- import './keyboard-manager-slimmer-f40dcb54.js';
62
- import './keyboard-manager-f5d13a34.js';
60
+ import './range-3c74e1c8.js';
61
+ import './keyboard-manager-slimmer-b3de042d.js';
62
+ import './keyboard-manager-53e8d8d0.js';
63
63
  import './vega-env-manager-8f8dc473.js';
64
64
  import './feature-flag-controller-3fd04ea9.js';
65
65
  import './index-9c9865c0.js';
@@ -2461,7 +2461,17 @@ class ValueController extends VegaSlimmer {
2461
2461
  const flushChangesWithDebounce = debounce(() => {
2462
2462
  void this.valueController.flushChanges(this.value);
2463
2463
  }, ValueController.VALUE_CHANGE_DEBOUNCE_TIME, this);
2464
- this.flushChangeObserver = new Observer(this.isAcceptableFlushChange.bind(this), flushChangesWithDebounce);
2464
+ this.flushChangeObserver = new Observer(this.isAcceptableFlushChange.bind(this), (payload) => {
2465
+ // When a handler asks to bypass the debounce (direct user gestures like `beforeinput`),
2466
+ // invoke `flushChanges` immediately with the payload as-is. Defaults live on the emitter
2467
+ // side (`BaseHandler.flushOptions`) — the observer trusts the payload and does not
2468
+ // re-apply fallback values, so there is a single source of truth.
2469
+ if (payload && payload.bypassDebounce) {
2470
+ void this.valueController.flushChanges(this.value, payload.recordHistory, payload.updateSource);
2471
+ return;
2472
+ }
2473
+ flushChangesWithDebounce();
2474
+ });
2465
2475
  ChangeManager.register(domNodeSubjectFactory.getSubject(this.host, VegaInternalRichTextEditorFlushChanges), this.flushChangeObserver);
2466
2476
  }
2467
2477
  /**
@@ -2622,12 +2632,44 @@ class RichTextContentController {
2622
2632
  }
2623
2633
  }
2624
2634
 
2635
+ /**
2636
+ * Applies an ordered list of leaf content actions as one flushable unit, so a `beforeinput` handler
2637
+ * emits a single flush through the shared action pipeline instead of marking each leaf action flushable.
2638
+ */
2639
+ class SequentialCompositionAction extends ModifyContentAction {
2640
+ constructor(steps, flushPayload = {}) {
2641
+ super();
2642
+ this.steps = steps;
2643
+ this.isFlushable = true;
2644
+ this.type = ModifyContentActionType.SEQUENTIAL_COMPOSITION;
2645
+ this.flushPayload = flushPayload;
2646
+ }
2647
+ }
2648
+
2625
2649
  const ROOT_CONTAINER_CLASS_NAME = 'rich-text-content';
2626
2650
  /** This code snippet is defining an abstract class named `BaseHandler` with an abstract method `execute`. */
2627
2651
  class BaseHandler {
2652
+ constructor() {
2653
+ /**
2654
+ * Default flush payload emitted after `handleEvent` completes. This is the single source of
2655
+ * truth for the defaults — the observer does not re-apply any fallback values. Subclasses may override
2656
+ * this field to opt out of flushing (assign `undefined`) or to change the defaults. Each instance
2657
+ * owns its own copy so mutations from within `handleEvent` (e.g. `InsertTextHandler` updating
2658
+ * `updateSource`) never leak across handler instances.
2659
+ */
2660
+ this.flushOptions = {
2661
+ bypassDebounce: true,
2662
+ recordHistory: true,
2663
+ updateSource: RTEUpdateSource.Default,
2664
+ };
2665
+ }
2628
2666
  /**
2629
2667
  * The function `execute` initializes the current state and selection, and then handles an event if provided.
2630
2668
  *
2669
+ * Contract: `handleEvent` MUST be synchronous. A handler that mutates the value returns the
2670
+ * `CompositionStep[]` it applied through `applyComposition`; the flush is then routed through the
2671
+ * shared action pipeline. Handlers that do not mutate the value return nothing
2672
+ *
2631
2673
  * @param {VegaRTEContent} currentState - The current state of the VegaRTE content.
2632
2674
  * @param {SelectionController} selectionController - Manages the selection of items in the user interface.
2633
2675
  * @param {HTMLElement} richTextEditor - The current rich text editor component
@@ -2636,7 +2678,20 @@ class BaseHandler {
2636
2678
  execute(currentState, selectionController, richTextEditor, event) {
2637
2679
  this.initCurrentStateAndSelection(currentState, selectionController);
2638
2680
  this.setCurrentRichTextEditor(richTextEditor);
2639
- this.handleEvent(event);
2681
+ const steps = this.handleEvent(event);
2682
+ this.applyComposition(steps);
2683
+ }
2684
+ /**
2685
+ * Applies the collected leaf actions as a single flushable `SequentialCompositionAction`, so the value
2686
+ * update and its flush run through the same action pipeline used by every other flushable operation.
2687
+ * Handlers call this before enqueuing selection so caret math reads post-apply node state.
2688
+ *
2689
+ * @param {CompositionStep[]} steps - The ordered leaf actions to apply against their own targets.
2690
+ */
2691
+ applyComposition(steps) {
2692
+ if (Array.isArray(steps)) {
2693
+ this.currentState.apply(new SequentialCompositionAction(steps, this.flushOptions));
2694
+ }
2640
2695
  }
2641
2696
  /**
2642
2697
  * The function `isRootContainer` checks if an HTML element is a root container with a class of 'rich-text-content'.
@@ -2725,25 +2780,40 @@ class InsertTextHandler extends BaseHandler {
2725
2780
  * Update the state value when user type character
2726
2781
  *
2727
2782
  * @param {InputEvent} event - The input event object
2783
+ * @returns {Nullable<CompositionStep[]>} The content actions the base handler applies as one flushable unit.
2728
2784
  */
2729
2785
  handleEvent(event) {
2786
+ // The composition input controller stamps its synthesized `beforeinput` events with the
2787
+ // composition update source; pick that up so the flush notification carries the right
2788
+ // source without the caller having to inspect the event.
2789
+ if (this.flushOptions) {
2790
+ this.flushOptions.updateSource =
2791
+ event[RTE_UPDATE_SOURCE_KEY] === RTEUpdateSource.Composition
2792
+ ? RTEUpdateSource.Composition
2793
+ : RTEUpdateSource.Default;
2794
+ }
2730
2795
  const text = event.data;
2731
2796
  const currentRange = this.selectionController.getCurrentRange();
2732
2797
  const { startContainer, startOffset } = currentRange;
2733
2798
  const selectedNodes = this.selectionController.getSelectedNodes();
2799
+ const steps = [];
2800
+ // The caret move is appended as the final composition step so content + caret apply and flush atomically.
2801
+ let caretNode = null;
2802
+ let caretOffset = 0;
2803
+ let updateFlag = false;
2734
2804
  if (selectedNodes.length < 2) {
2735
2805
  if (!selectedNodes.length && this.isRootContainer(startContainer)) {
2736
- const cursorNode = this.insertTextToRoot(text);
2737
- this.selectionController.enqueueSelectionRangeFutureState(cursorNode, text.length);
2806
+ caretNode = this.insertTextToRoot(text, steps);
2807
+ caretOffset = text.length;
2738
2808
  }
2739
2809
  else if (selectedNodes[0] instanceof RTETextNode) {
2740
2810
  if (selectedNodes[0].isContentEditable()) {
2741
2811
  let nextOffset = startOffset + text.length;
2742
- let updateFlag = false;
2743
2812
  let cursorNode = selectedNodes[0];
2744
2813
  if (cursorNode.text === '\n') {
2745
- cursorNode = this.insertTextToLineBreakNode(cursorNode, text);
2746
- updateFlag = true;
2814
+ cursorNode = this.insertTextToLineBreakNode(cursorNode, text, steps);
2815
+ // UpdateTextAction replaces the \n with the input, so the caret lands at the text end.
2816
+ nextOffset = text.length;
2747
2817
  }
2748
2818
  else {
2749
2819
  if (startContainer.nodeValue === ZERO_WIDTH_SPACE &&
@@ -2752,40 +2822,54 @@ class InsertTextHandler extends BaseHandler {
2752
2822
  startContainer.nodeValue = '';
2753
2823
  nextOffset = nextOffset - ZERO_WIDTH_SPACE.length;
2754
2824
  }
2755
- if (cursorNode instanceof RTETextNode) {
2756
- updateFlag = true;
2757
- cursorNode.apply(new ReplaceSelectedTextAction(text, currentRange));
2758
- }
2825
+ steps.push({
2826
+ target: cursorNode,
2827
+ action: new ReplaceSelectedTextAction(text, currentRange),
2828
+ });
2759
2829
  }
2760
- updateFlag &&
2761
- this.selectionController.enqueueSelectionRangeFutureState(cursorNode, Math.min(nextOffset, cursorNode['text'].length));
2830
+ caretNode = cursorNode;
2831
+ // Content applies later via the composition, so use the post-apply offset directly (no pre-apply clamp).
2832
+ caretOffset = nextOffset;
2762
2833
  }
2763
2834
  else {
2764
- selectedNodes[0].parent.apply(new InsertTextToDecoratorNodeAction(selectedNodes[0], text, startOffset));
2835
+ steps.push({
2836
+ target: selectedNodes[0].parent,
2837
+ action: new InsertTextToDecoratorNodeAction(selectedNodes[0], text, startOffset),
2838
+ });
2765
2839
  }
2766
2840
  }
2767
2841
  }
2768
2842
  else {
2769
2843
  // The selected nodes is multiple nodes
2770
2844
  const cursorNode = this.removeSelectionRange(true);
2845
+ updateFlag = true;
2771
2846
  if (cursorNode instanceof RTETextNode) {
2772
- cursorNode.apply(new ReplaceSelectedTextAction(text, currentRange));
2773
- this.selectionController.enqueueSelectionRangeFutureState(cursorNode, Math.min(startOffset + text.length, cursorNode.text.length));
2847
+ steps.push({ target: cursorNode, action: new ReplaceSelectedTextAction(text, currentRange) });
2848
+ caretNode = cursorNode;
2849
+ caretOffset = startOffset + text.length;
2774
2850
  }
2775
2851
  }
2852
+ if (caretNode) {
2853
+ steps.push({
2854
+ target: this.currentState,
2855
+ action: new UpdateCursorPositionAction(caretNode, caretOffset),
2856
+ });
2857
+ }
2858
+ return updateFlag || steps.length > 0 ? steps : undefined;
2776
2859
  }
2777
2860
  /**
2778
2861
  * Insert the text in root element when root container is empty, should create text block and text node
2779
2862
  *
2780
2863
  * @param {string} text The insert text
2781
- * @returns {RTETextNode} The new create text node
2864
+ * @param {CompositionStep[]} steps The composition steps collector to append the update action to
2865
+ * @returns {Nullable<RTETextNode>} The new create text node
2782
2866
  */
2783
- insertTextToRoot(text) {
2867
+ insertTextToRoot(text, steps) {
2784
2868
  if (this.currentState &&
2785
2869
  this.currentState.children[0] &&
2786
2870
  this.currentState.children[0] instanceof RTETextBlock) {
2787
2871
  const firstNode = this.currentState.children[0].children[0];
2788
- firstNode.apply(new UpdateTextAction(text));
2872
+ steps.push({ target: firstNode, action: new UpdateTextAction(text) });
2789
2873
  return firstNode;
2790
2874
  }
2791
2875
  }
@@ -2794,20 +2878,24 @@ class InsertTextHandler extends BaseHandler {
2794
2878
  *
2795
2879
  * @param {RTETextNode} lineBreakNode The current line break node, the text value is \n
2796
2880
  * @param {string} text The text need to insert
2881
+ * @param {CompositionStep[]} steps The composition steps collector to append the resulting action to
2797
2882
  * @returns {Nullable<RTETextNode>} The new text node or the current line break node
2798
2883
  */
2799
- insertTextToLineBreakNode(lineBreakNode, text) {
2884
+ insertTextToLineBreakNode(lineBreakNode, text, steps) {
2800
2885
  const { startOffset, endOffset } = this.selectionController.getCurrentRange();
2801
2886
  const textBlock = lineBreakNode.parent;
2802
2887
  if (textBlock instanceof RTETextBlock) {
2803
2888
  const index = textBlock.children.indexOf(lineBreakNode);
2804
2889
  if (startOffset === 0 && startOffset === endOffset && textBlock.children[index + 1]) {
2805
2890
  const newTextNode = lineBreakNode.cloneWithText(text);
2806
- textBlock.apply(new InsertChildrenBeforeAction(lineBreakNode, newTextNode));
2891
+ steps.push({
2892
+ target: textBlock,
2893
+ action: new InsertChildrenBeforeAction(lineBreakNode, newTextNode),
2894
+ });
2807
2895
  return newTextNode;
2808
2896
  }
2809
2897
  else {
2810
- lineBreakNode.apply(new UpdateTextAction(text));
2898
+ steps.push({ target: lineBreakNode, action: new UpdateTextAction(text) });
2811
2899
  return lineBreakNode;
2812
2900
  }
2813
2901
  }
@@ -2818,20 +2906,19 @@ class InsertTextHandler extends BaseHandler {
2818
2906
  class InsertParagraphHandler extends BaseHandler {
2819
2907
  /**
2820
2908
  * Create new paragraph node and add node to state value
2909
+ *
2910
+ * @returns {CompositionStep[] | void} The content + caret steps applied atomically as one flushable composition.
2821
2911
  */
2822
2912
  handleEvent() {
2823
2913
  const selectedBlocks = this.selectionController.getSelectedBlocks();
2824
2914
  if (selectedBlocks.length) {
2825
- if (selectedBlocks.length < 2) {
2826
- this.breakSingleBlock();
2827
- }
2828
- else {
2829
- this.breakMultipleBlocks();
2830
- }
2915
+ return selectedBlocks.length < 2 ? this.breakSingleBlock() : this.breakMultipleBlocks();
2831
2916
  }
2832
2917
  }
2833
2918
  /**
2834
2919
  * Handles breaking blocks in an RTE editor based on the current selection and position.
2920
+ *
2921
+ * @returns {CompositionStep[]} The content + caret steps for the multi-block break.
2835
2922
  */
2836
2923
  breakMultipleBlocks() {
2837
2924
  const selectedBlocks = this.selectionController.getSelectedBlocks();
@@ -2869,36 +2956,71 @@ class InsertParagraphHandler extends BaseHandler {
2869
2956
  */
2870
2957
  if (firstBlock.type !== lastBlock.type &&
2871
2958
  range.startContainer.nodeType === range.endContainer.nodeType) {
2872
- firstBlock.apply(new MergeTwoBlocksNodesAction(lastBlock));
2873
- const splitAction = new SplitBlockWithNodeAction(cursorNode, cursorNode['text'].length);
2874
- firstBlock.apply(splitAction);
2875
- this.switchCaretPositionToNextElement(splitAction.newBlock);
2876
- return;
2959
+ const mergeStep = {
2960
+ target: firstBlock,
2961
+ action: new MergeTwoBlocksNodesAction(lastBlock),
2962
+ };
2963
+ // Split offset is read at apply time, after the merge step has run.
2964
+ // eslint-disable-next-line jsdoc/require-jsdoc
2965
+ const splitStep = () => ({
2966
+ target: firstBlock,
2967
+ action: new SplitBlockWithNodeAction(cursorNode, cursorNode['text'].length),
2968
+ });
2969
+ // eslint-disable-next-line jsdoc/require-jsdoc
2970
+ const caretStep = (context) => {
2971
+ const splitAction = context.getAction(ModifyContentActionType.SPLIT_BLOCK_WITH_NODE);
2972
+ if (splitAction) {
2973
+ return this.caretToNextElement(splitAction.newBlock);
2974
+ }
2975
+ };
2976
+ return [mergeStep, splitStep, caretStep];
2877
2977
  }
2878
2978
  }
2879
- this.selectionController.enqueueSelectionRangeFutureState(cursorNode, range.startOffset);
2979
+ return [
2980
+ {
2981
+ target: this.currentState,
2982
+ action: new UpdateCursorPositionAction(cursorNode, range.startOffset),
2983
+ },
2984
+ ];
2880
2985
  }
2881
2986
  /**
2882
2987
  * Handles breaking a single block in an RTE editor based on the current selection and position.
2988
+ *
2989
+ * @returns {CompositionStep[]} The content + caret steps for the single-block break.
2883
2990
  */
2884
2991
  breakSingleBlock() {
2885
2992
  const cursorNode = this.removeSelectionRange();
2886
2993
  const currentBlock = cursorNode instanceof RTENode ? cursorNode.parent : cursorNode;
2887
2994
  const { startOffset } = this.selectionController.getCurrentRange();
2995
+ let result = [];
2888
2996
  if (currentBlock) {
2889
- const breakAction = new InsertNewParagraphAction(cursorNode, startOffset);
2890
- currentBlock.apply(breakAction);
2891
- this.switchCaretPositionToNextElement(breakAction.newBlock);
2997
+ const breakStep = {
2998
+ target: currentBlock,
2999
+ action: new InsertNewParagraphAction(cursorNode, startOffset),
3000
+ };
3001
+ // eslint-disable-next-line jsdoc/require-jsdoc
3002
+ const caretStep = (context) => {
3003
+ const breakAction = context.getAction(ModifyContentActionType.INSERT_NEW_PARAGRAPH);
3004
+ if (breakAction) {
3005
+ return this.caretToNextElement(breakAction.newBlock);
3006
+ }
3007
+ };
3008
+ result = [breakStep, caretStep];
2892
3009
  }
3010
+ return result;
2893
3011
  }
2894
3012
  /**
2895
- * Moves the caret to the next block element in a rich text editor.
3013
+ * Builds the caret operation that moves onto the first child of the newly created block.
2896
3014
  *
2897
- * @param {RTEBlock} newBlock - Represents a new create block element in a rich text editor.
3015
+ * @param {Nullable<RTEBlock>} newBlock - The block created by the break, or null when none was created.
3016
+ * @returns {CompositionOperation | void} The caret operation, or nothing when there is no target block.
2898
3017
  */
2899
- switchCaretPositionToNextElement(newBlock) {
3018
+ caretToNextElement(newBlock) {
2900
3019
  if (newBlock && newBlock.children) {
2901
- this.selectionController.enqueueSelectionRangeFutureState(newBlock.children[0], 0);
3020
+ return {
3021
+ target: this.currentState,
3022
+ action: new UpdateCursorPositionAction(newBlock.children[0], 0),
3023
+ };
2902
3024
  }
2903
3025
  }
2904
3026
  }
@@ -2934,20 +3056,16 @@ class lineBreakMultipleBlocksAction extends ModifyContentAction {
2934
3056
  class InsertLineBreakHandler extends BaseHandler {
2935
3057
  /**
2936
3058
  * Create new line break node and add node to state value
3059
+ *
3060
+ * @returns {Nullable<CompositionStep[]>} The content + caret steps applied atomically as one flushable composition.
2937
3061
  */
2938
3062
  handleEvent() {
2939
- const range = this.selectionController.getCurrentRange();
2940
3063
  const selectedBlocks = this.selectionController.getSelectedBlocks();
2941
- if (this.isRootContainer(range.startContainer)) {
2942
- this.breakNewBlock();
2943
- }
2944
3064
  if (selectedBlocks.length) {
2945
- if (selectedBlocks.length < 2) {
2946
- this.breakSingleBlock();
2947
- }
2948
- else {
2949
- this.breakMultipleBlocks();
2950
- }
3065
+ return selectedBlocks.length < 2 ? this.breakSingleBlock() : this.breakMultipleBlocks();
3066
+ }
3067
+ else if (this.isRootContainer(this.selectionController.getCurrentRange().startContainer)) {
3068
+ return this.breakNewBlock();
2951
3069
  }
2952
3070
  }
2953
3071
  /**
@@ -2956,14 +3074,19 @@ class InsertLineBreakHandler extends BaseHandler {
2956
3074
  * <span></span>
2957
3075
  * <span></span>
2958
3076
  * </p>
3077
+ *
3078
+ * @returns {Nullable<CompositionStep[]>} The content + caret steps for the empty root break.
2959
3079
  */
2960
3080
  breakNewBlock() {
2961
3081
  if (this.currentState &&
2962
3082
  this.currentState.children[0] &&
2963
3083
  this.currentState.children[0] instanceof RTETextBlock) {
2964
- const lineBreakAction = new LineBreakSingleBlockAction(this.currentState.children[0].children[0], 0);
2965
- this.currentState.children[0].apply(lineBreakAction);
2966
- this.switchCaretPositionToSpecifiedNode(lineBreakAction.lineBreakNode);
3084
+ const targetBlock = this.currentState.children[0];
3085
+ const lineBreakStep = {
3086
+ target: targetBlock,
3087
+ action: new LineBreakSingleBlockAction(targetBlock.children[0], 0),
3088
+ };
3089
+ return [lineBreakStep, this.caretToSingleBlockNextNode()];
2967
3090
  }
2968
3091
  }
2969
3092
  /**
@@ -2977,36 +3100,68 @@ class InsertLineBreakHandler extends BaseHandler {
2977
3100
  * <br>
2978
3101
  * <span>xt</span>
2979
3102
  * </p>
3103
+ *
3104
+ * @returns {CompositionStep[]} The content + caret steps for the single-block break.
2980
3105
  */
2981
3106
  breakSingleBlock() {
2982
3107
  const range = this.selectionController.getCurrentRange();
2983
3108
  const cursorNode = this.removeSelectionRange();
2984
3109
  const currentBlock = cursorNode.parent;
3110
+ let result = [];
2985
3111
  if (currentBlock) {
2986
- const lineBreakAction = new LineBreakSingleBlockAction(cursorNode, range.startOffset);
2987
- currentBlock.apply(lineBreakAction);
2988
- if (lineBreakAction.lineBreakNode) {
2989
- this.switchCaretPositionToSpecifiedNode(lineBreakAction.lineBreakNode);
2990
- }
3112
+ const contentStep = {
3113
+ target: currentBlock,
3114
+ action: new LineBreakSingleBlockAction(cursorNode, range.startOffset),
3115
+ };
3116
+ result = [contentStep, this.caretToSingleBlockNextNode()];
2991
3117
  }
3118
+ return result;
2992
3119
  }
2993
3120
  /**
2994
3121
  * Handles breaking blocks in an RTE editor based on the current selection and position.
3122
+ *
3123
+ * @returns {CompositionStep[]} The content + caret steps for the multi-block break.
2995
3124
  */
2996
3125
  breakMultipleBlocks() {
2997
3126
  const selectedBlocks = this.selectionController.getSelectedBlocks();
2998
3127
  const cursorNode = this.removeSelectionRange();
2999
- const lineBreakAction = new lineBreakMultipleBlocksAction(selectedBlocks);
3000
- cursorNode.parent.apply(lineBreakAction);
3001
- this.switchCaretPositionToSpecifiedNode(lineBreakAction.lineBreakNode);
3128
+ const contentStep = {
3129
+ target: cursorNode.parent,
3130
+ action: new lineBreakMultipleBlocksAction(selectedBlocks),
3131
+ };
3132
+ // eslint-disable-next-line jsdoc/require-jsdoc
3133
+ const caretStep = (context) => {
3134
+ const lineBreakAction = context.getAction(ModifyContentActionType.LINE_BREAK_MULTIPLE_BLOCKS);
3135
+ if (lineBreakAction && lineBreakAction.lineBreakNode) {
3136
+ return this.caretOperationToNextNode(lineBreakAction.lineBreakNode);
3137
+ }
3138
+ };
3139
+ return [contentStep, caretStep];
3140
+ }
3141
+ /**
3142
+ * Builds the caret step that reads the applied single-block line break to place the caret after it.
3143
+ *
3144
+ * @returns {CompositionStep} The dependent caret step.
3145
+ */
3146
+ caretToSingleBlockNextNode() {
3147
+ return (context) => {
3148
+ const lineBreakAction = context.getAction(ModifyContentActionType.LINE_BREAK_SINGLE_BLOCK);
3149
+ if (lineBreakAction && lineBreakAction.lineBreakNode) {
3150
+ return this.caretOperationToNextNode(lineBreakAction.lineBreakNode);
3151
+ }
3152
+ };
3002
3153
  }
3003
3154
  /**
3004
- * Moves the caret to the next node element in a rich text editor.
3155
+ * Builds the caret operation that moves onto the node following the inserted line break.
3005
3156
  *
3006
- * @param {RTENode} lineBreakNode - Represents a node element in a rich text editor.
3157
+ * @param {RTENode} lineBreakNode - The inserted line break node.
3158
+ * @returns {CompositionOperation} The caret operation.
3007
3159
  */
3008
- switchCaretPositionToSpecifiedNode(lineBreakNode) {
3009
- this.selectionController.enqueueSelectionRangeFutureState(this.getNextRTENode(lineBreakNode), 0);
3160
+ caretOperationToNextNode(lineBreakNode) {
3161
+ return {
3162
+ target: this.currentState,
3163
+ action: new UpdateCursorPositionAction(this.getNextRTENode(lineBreakNode), 0),
3164
+ };
3010
3165
  }
3011
3166
  /**
3012
3167
  * Returns the next sibling node of a given block element in a rich text editor.
@@ -3043,15 +3198,76 @@ class DeleteBlockContentAction extends ModifyContentAction {
3043
3198
  class AbstractDeleteContentHandler extends BaseHandler {
3044
3199
  /**
3045
3200
  * Delete the selected node(s) from the current state.
3201
+ *
3202
+ * @returns {CompositionStep[]} The content + caret steps applied atomically as one flushable composition.
3046
3203
  */
3047
3204
  handleEvent() {
3048
3205
  const selectedBlocks = this.selectionController.getSelectedBlocks();
3049
3206
  if (selectedBlocks.length >= 2) {
3050
3207
  this.deleteContentWithMultipleNodes();
3208
+ return [];
3051
3209
  }
3052
- else {
3053
- this.deleteContentWithSingleBlock();
3054
- }
3210
+ return this.deleteContentWithSingleBlock();
3211
+ }
3212
+ /**
3213
+ * Builds the ordered steps for a single-block deletion: the delete runs first, then a caret step
3214
+ * reads the delete action's post-apply `previousNode`/`nextNode` to decide where the caret lands.
3215
+ *
3216
+ * @param {RTENode} resolvedNode - The node the deletion is anchored on.
3217
+ * @param {number} resolvedOffset - The caret offset within `resolvedNode` at deletion time.
3218
+ * @param {Nullable<RTENode>} caretAnchor - A node the caret must stay on regardless of the delete result.
3219
+ * @returns {CompositionStep[]} The delete step followed by the dependent caret step.
3220
+ */
3221
+ buildDeleteSteps(resolvedNode, resolvedOffset, caretAnchor) {
3222
+ // eslint-disable-next-line jsdoc/require-jsdoc
3223
+ const deleteStep = () => ({
3224
+ target: resolvedNode.parent,
3225
+ action: new DeleteBlockContentAction(resolvedNode, resolvedOffset),
3226
+ });
3227
+ // eslint-disable-next-line jsdoc/require-jsdoc
3228
+ const caretStep = (context) => {
3229
+ if (caretAnchor) {
3230
+ // A non-editable anchor (e.g. a token) expresses its caret position at the parent-block
3231
+ // level, so use its index within the parent to land right before it instead of jumping
3232
+ // to the block start.
3233
+ const caretOffset = caretAnchor.isContentEditable()
3234
+ ? 0
3235
+ : caretAnchor.parent.children.indexOf(caretAnchor);
3236
+ return {
3237
+ target: this.currentState,
3238
+ action: new UpdateCursorPositionAction(caretAnchor, caretOffset),
3239
+ };
3240
+ }
3241
+ const deleteAction = context.getAction(ModifyContentActionType.DELETE_BLOCK_CONTENT);
3242
+ if (deleteAction && deleteAction.previousNode) {
3243
+ const nextOffset = deleteAction.previousNode === resolvedNode
3244
+ ? Math.max(0, resolvedOffset - 1)
3245
+ : deleteAction.previousNode.getRangeEndOffset();
3246
+ return {
3247
+ target: this.currentState,
3248
+ action: new UpdateCursorPositionAction(deleteAction.previousNode, nextOffset),
3249
+ };
3250
+ }
3251
+ if (deleteAction && deleteAction.nextNode) {
3252
+ return {
3253
+ target: this.currentState,
3254
+ action: new UpdateCursorPositionAction(deleteAction.nextNode, 0),
3255
+ };
3256
+ }
3257
+ if (this.currentState.children.length === 0) {
3258
+ // Add an empty paragraph if the delete removed all content to keep a valid caret position.
3259
+ const paragraph = this.createEmptyParagraph();
3260
+ return [
3261
+ { target: this.currentState, action: new AppendChildrenAction([paragraph]) },
3262
+ {
3263
+ target: this.currentState,
3264
+ action: new UpdateCursorPositionAction(paragraph.children[0], 1),
3265
+ },
3266
+ ];
3267
+ }
3268
+ return undefined;
3269
+ };
3270
+ return [deleteStep, caretStep];
3055
3271
  }
3056
3272
  /**
3057
3273
  * Computes the caret position one step to the right, used to translate a forward delete into a backspace.
@@ -3180,27 +3396,21 @@ class AbstractDeleteContentHandler extends BaseHandler {
3180
3396
  block.parent.apply(new RemoveChildrenAction(block));
3181
3397
  }
3182
3398
  }
3183
- /**
3184
- * Creates a new paragraph element with a text node and appends it to the current state.
3185
- */
3186
- insertDefaultParagraph() {
3187
- const paragraph = this.createEmptyParagraph();
3188
- this.currentState.apply(new AppendChildrenAction([paragraph]));
3189
- this.selectionController.enqueueSelectionRangeFutureState(paragraph.children[0], 1);
3190
- }
3191
3399
  }
3192
3400
 
3193
3401
  /** Handles a delete (rightward) deletion of content within a VegaRTE editor. User press delete will trigger this method */
3194
3402
  class ForwardDeleteContentHandler extends AbstractDeleteContentHandler {
3195
3403
  /**
3196
3404
  * Handles a delete (rightward) deletion of content within a single block in an RTE editor.
3405
+ *
3406
+ * @returns {Nullable<CompositionStep[]>} The delete + caret steps, empty when the deletion is delegated or a no-op.
3197
3407
  */
3198
3408
  deleteContentWithSingleBlock() {
3199
3409
  const range = this.selectionController.getCurrentRange();
3200
3410
  const { startOffset, endOffset, startContainer, endContainer } = range;
3201
3411
  if (startOffset !== endOffset || startContainer !== endContainer) {
3202
3412
  this.deleteContentWithMultipleNodes();
3203
- return;
3413
+ return [];
3204
3414
  }
3205
3415
  const targetNode = this.selectionController.getSelectedNodes()[0];
3206
3416
  // The node that should hold the caret after a forward delete removes a non-editable
@@ -3224,7 +3434,8 @@ class ForwardDeleteContentHandler extends AbstractDeleteContentHandler {
3224
3434
  const forwardPosition = this.getForwardDeletePosition(targetNode, startOffset);
3225
3435
  // The caret is at the very end of the content, there is nothing to delete forward.
3226
3436
  if (!forwardPosition) {
3227
- return;
3437
+ // Nothing changes, so we return undefined to indicate no composition steps are needed.
3438
+ return undefined;
3228
3439
  }
3229
3440
  // Mirror backspace at heterogeneous block boundaries: a forward delete that crosses
3230
3441
  // into a following block of a different type (e.g. paragraph → list-item, or into an
@@ -3235,8 +3446,11 @@ class ForwardDeleteContentHandler extends AbstractDeleteContentHandler {
3235
3446
  if (targetNode &&
3236
3447
  forwardPosition.node.parent !== targetNode.parent &&
3237
3448
  forwardPosition.node.parent.type !== targetNode.parent.type) {
3238
- this.selectionController.enqueueSelectionRangeFutureState(forwardPosition.node, 0);
3239
- return;
3449
+ const caretOperation = {
3450
+ target: this.currentState,
3451
+ action: new UpdateCursorPositionAction(forwardPosition.node, 0),
3452
+ };
3453
+ return [caretOperation];
3240
3454
  }
3241
3455
  // When the caret sits at the start of a non-editable leading node (e.g. a function
3242
3456
  // keyword or a token), a forward delete removes that node. Visually the caret stays
@@ -3251,34 +3465,9 @@ class ForwardDeleteContentHandler extends AbstractDeleteContentHandler {
3251
3465
  }
3252
3466
  /* istanbul ignore next */
3253
3467
  if (!resolvedNode) {
3254
- return;
3255
- }
3256
- const deleteAction = new DeleteBlockContentAction(resolvedNode, resolvedOffset);
3257
- resolvedNode.parent.apply(deleteAction);
3258
- if (forwardCaretAnchor) {
3259
- // A non-editable anchor (e.g. a token) expresses its caret position at the
3260
- // parent-block level: its range container is the parent element, so an offset of
3261
- // 0 would put the caret at the very start of the block (jumping to the far left)
3262
- // instead of just before the anchor. Use the anchor's index within its parent so
3263
- // the caret lands right before it, on the spot the deleted node used to occupy.
3264
- const forwardCaretOffset = forwardCaretAnchor.isContentEditable()
3265
- ? 0
3266
- : forwardCaretAnchor.parent.children.indexOf(forwardCaretAnchor);
3267
- this.selectionController.enqueueSelectionRangeFutureState(forwardCaretAnchor, forwardCaretOffset);
3268
- }
3269
- else if (deleteAction.previousNode) {
3270
- const nextOffset = deleteAction.previousNode === resolvedNode
3271
- ? Math.max(0, resolvedOffset - 1)
3272
- : deleteAction.previousNode.getRangeEndOffset();
3273
- this.selectionController.enqueueSelectionRangeFutureState(deleteAction.previousNode, nextOffset);
3274
- }
3275
- else if (deleteAction.nextNode) {
3276
- this.selectionController.enqueueSelectionRangeFutureState(deleteAction.nextNode, 0);
3277
- }
3278
- else if (this.currentState.children.length === 0) {
3279
- // Add a empty paragraph if delete all content to make sure the caret position
3280
- this.insertDefaultParagraph();
3468
+ return [];
3281
3469
  }
3470
+ return this.buildDeleteSteps(resolvedNode, resolvedOffset, forwardCaretAnchor);
3282
3471
  }
3283
3472
  }
3284
3473
 
@@ -3286,33 +3475,21 @@ class ForwardDeleteContentHandler extends AbstractDeleteContentHandler {
3286
3475
  class BackwardDeleteContentHandler extends AbstractDeleteContentHandler {
3287
3476
  /**
3288
3477
  * Handles a backspace (leftward) deletion of content within a single block in an RTE editor.
3478
+ *
3479
+ * @returns {Nullable<CompositionStep[]>} The delete + caret steps, empty when the deletion is delegated or a no-op.
3289
3480
  */
3290
3481
  deleteContentWithSingleBlock() {
3291
3482
  const range = this.selectionController.getCurrentRange();
3292
3483
  const { startOffset, endOffset, startContainer, endContainer } = range;
3293
3484
  if (startOffset !== endOffset || startContainer !== endContainer) {
3294
3485
  this.deleteContentWithMultipleNodes();
3295
- return;
3486
+ return [];
3296
3487
  }
3297
3488
  const targetNode = this.selectionController.getSelectedNodes()[0];
3298
3489
  if (!targetNode) {
3299
3490
  return;
3300
3491
  }
3301
- const deleteAction = new DeleteBlockContentAction(targetNode, startOffset);
3302
- targetNode.parent.apply(deleteAction);
3303
- if (deleteAction.previousNode) {
3304
- const nextOffset = deleteAction.previousNode === targetNode
3305
- ? Math.max(0, startOffset - 1)
3306
- : deleteAction.previousNode.getRangeEndOffset();
3307
- this.selectionController.enqueueSelectionRangeFutureState(deleteAction.previousNode, nextOffset);
3308
- }
3309
- else if (deleteAction.nextNode) {
3310
- this.selectionController.enqueueSelectionRangeFutureState(deleteAction.nextNode, 0);
3311
- }
3312
- else if (this.currentState.children.length === 0) {
3313
- // Add a empty paragraph if delete all content to make sure the caret position
3314
- this.insertDefaultParagraph();
3315
- }
3492
+ return this.buildDeleteSteps(targetNode, startOffset, null);
3316
3493
  }
3317
3494
  }
3318
3495
 
@@ -3342,53 +3519,57 @@ class InsertPasteHandler extends BaseHandler {
3342
3519
  * Update the state value when user paste html elements.
3343
3520
  *
3344
3521
  * @param {InputEvent} event - Paste event.
3522
+ * @returns {CompositionStep[]} The content + caret steps applied atomically as one flushable composition.
3345
3523
  */
3346
3524
  handleEvent(event) {
3347
3525
  const currentRange = this.selectionController.getCurrentRange();
3348
3526
  const payload = this.getPastePayload(event);
3349
- if (this.insertPlainTextInline(payload, currentRange)) {
3350
- return;
3527
+ const inlineSteps = this.insertPlainTextInline(payload, currentRange);
3528
+ if (inlineSteps) {
3529
+ return inlineSteps;
3351
3530
  }
3352
- const blocks = this.parsePastedElements(event);
3531
+ const blocks = this.parsePastedElements(event, currentRange);
3353
3532
  const startContainer = (currentRange === null || currentRange === void 0 ? void 0 : currentRange.startContainer) || undefined;
3354
3533
  if (!startContainer) {
3355
3534
  // When the selection/range is unavailable (e.g. the caret was lost while
3356
3535
  // the paste-mode chooser had focus), still append the pasted content to
3357
3536
  // the root so the paste is never silently dropped.
3358
- this.insertBlocksToRoot(blocks);
3537
+ return this.insertBlocksToRoot(blocks);
3359
3538
  }
3360
- else if (this.isRootContainer(startContainer)) {
3361
- this.insertBlocksToRoot(blocks);
3539
+ if (this.isRootContainer(startContainer)) {
3362
3540
  // TODO: Need to check below logic, it seems not correct https://gethired.atlassian.net/browse/VD-7779
3541
+ return this.insertBlocksToRoot(blocks);
3363
3542
  }
3364
- else if (this.isEmptyParagraph(startContainer)) {
3365
- this.insertBlocksBeforeEmptyBlock(blocks, currentRange);
3366
- }
3367
- else {
3368
- this.insertBlocksToContent(blocks, currentRange);
3543
+ if (this.isEmptyParagraph(startContainer)) {
3544
+ return this.insertBlocksBeforeEmptyBlock(blocks, currentRange);
3369
3545
  }
3546
+ return this.insertBlocksToContent(blocks, currentRange);
3370
3547
  }
3371
3548
  /**
3372
3549
  * Inserts plain-text paste content into the current text node at caret position.
3373
3550
  *
3374
3551
  * @param {RTEPastePayload} payload - Clipboard payload.
3375
3552
  * @param {RTERange} currentRange - Current selection range.
3376
- * @returns {boolean} True when inline insertion is handled.
3553
+ * @returns {CompositionStep[] | undefined} The content + caret steps when inline insertion applies, otherwise undefined.
3377
3554
  */
3378
3555
  insertPlainTextInline(payload, currentRange) {
3379
3556
  var _a, _b;
3380
3557
  const selectedNodes = ((_b = (_a = this.selectionController).getSelectedNodes) === null || _b === void 0 ? void 0 : _b.call(_a)) || [];
3381
3558
  if (!this.shouldPasteAsInlinePlainText(payload, currentRange, selectedNodes)) {
3382
- return false;
3559
+ return undefined;
3383
3560
  }
3384
3561
  const text = payload.text.replace(/\r\n?/g, '\n');
3385
3562
  const cursorNode = selectedNodes.find((node) => node instanceof RTETextNode) || currentRange.startNode;
3386
3563
  if (!(cursorNode instanceof RTETextNode)) {
3387
- return false;
3564
+ return undefined;
3388
3565
  }
3389
- cursorNode.apply(new ReplaceSelectedTextAction(text, currentRange));
3390
- this.selectionController.enqueueSelectionRangeFutureState(cursorNode, currentRange.startOffset + text.length);
3391
- return true;
3566
+ return [
3567
+ { target: cursorNode, action: new ReplaceSelectedTextAction(text, currentRange) },
3568
+ {
3569
+ target: this.currentState,
3570
+ action: new UpdateCursorPositionAction(cursorNode, currentRange.startOffset + text.length),
3571
+ },
3572
+ ];
3392
3573
  }
3393
3574
  /**
3394
3575
  * Determines whether the payload should be inserted as inline plain text.
@@ -3453,68 +3634,116 @@ class InsertPasteHandler extends BaseHandler {
3453
3634
  * Insert the blocks to root
3454
3635
  *
3455
3636
  * @param { RTEContentBlock[]} blocks - blocks
3637
+ * @returns {CompositionStep[]} The append step for the root.
3456
3638
  */
3457
3639
  insertBlocksToRoot(blocks) {
3458
- this.currentState.apply(new AppendChildrenAction(blocks));
3640
+ return [{ target: this.currentState, action: new AppendChildrenAction(blocks) }];
3459
3641
  }
3460
3642
  /**
3461
3643
  * Insert the blocks into the current content block at the specified range.
3462
3644
  *
3463
3645
  * @param { RTEContentBlock[]} blocks - blocks
3464
3646
  * @param { RTERange } rteRange - rteRange
3647
+ * @returns {CompositionStep[]} The content + caret steps for the content branch.
3465
3648
  */
3466
3649
  insertBlocksToContent(blocks, rteRange) {
3467
- var _a;
3468
3650
  const isCollapsedRange = rteRange.startNode === rteRange.endNode && rteRange.startOffset === rteRange.endOffset;
3469
3651
  const cursorNode = isCollapsedRange
3470
3652
  ? rteRange.startNode
3471
3653
  : this.removeSelectionRange();
3472
3654
  if (cursorNode && cursorNode.parent) {
3473
- const pasteAction = new PasteContentAction(blocks, cursorNode, rteRange.startOffset, rteRange);
3474
- cursorNode.parent.apply(pasteAction);
3475
- if (pasteAction.futureFocusNode) {
3476
- this.selectionController.enqueueSelectionRangeFutureState(pasteAction.futureFocusNode, (_a = pasteAction.futureFocusNodeOffset) !== null && _a !== void 0 ? _a : 0);
3477
- }
3478
- else if (pasteAction.futureFocusBlock) {
3479
- this.switchCaretPositionToNextElement(pasteAction.futureFocusBlock, pasteAction.futureFocusAtEnd);
3480
- }
3481
- }
3482
- else {
3483
- // No resolvable cursor position: fall back to appending at the root so
3484
- // the pasted content is preserved instead of being discarded.
3485
- this.insertBlocksToRoot(blocks);
3655
+ const contentStep = {
3656
+ target: cursorNode.parent,
3657
+ action: new PasteContentAction(blocks, cursorNode, rteRange.startOffset, rteRange),
3658
+ };
3659
+ // eslint-disable-next-line jsdoc/require-jsdoc
3660
+ const caretStep = (context) => {
3661
+ var _a;
3662
+ const pasteAction = context.getAction(ModifyContentActionType.PASTE_CONTENT);
3663
+ if (pasteAction && pasteAction.futureFocusNode) {
3664
+ return {
3665
+ target: this.currentState,
3666
+ action: new UpdateCursorPositionAction(pasteAction.futureFocusNode, (_a = pasteAction.futureFocusNodeOffset) !== null && _a !== void 0 ? _a : 0),
3667
+ };
3668
+ }
3669
+ if (pasteAction && pasteAction.futureFocusBlock) {
3670
+ return this.caretToBlockOperation(pasteAction.futureFocusBlock, pasteAction.futureFocusAtEnd);
3671
+ }
3672
+ };
3673
+ return [contentStep, caretStep];
3486
3674
  }
3675
+ // No resolvable cursor position: fall back to appending at the root so
3676
+ // the pasted content is preserved instead of being discarded.
3677
+ return this.insertBlocksToRoot(blocks);
3487
3678
  }
3488
3679
  /**
3489
3680
  * Insert the blocks before to current block
3490
3681
  *
3491
3682
  * @param { RTEContentBlock[]} blocks - blocks
3492
3683
  * @param { RTERange } rteRange - rteRange
3684
+ * @returns {CompositionStep[]} The content + caret steps for the empty-paragraph branch.
3493
3685
  */
3494
3686
  insertBlocksBeforeEmptyBlock(blocks, rteRange) {
3495
3687
  const cursorNode = this.removeSelectionRange();
3496
3688
  const currentBlock = cursorNode === null || cursorNode === void 0 ? void 0 : cursorNode.parent;
3497
3689
  if (currentBlock) {
3498
- const pasteAction = new PasteContentAction(blocks, cursorNode, 0, rteRange);
3499
- currentBlock.apply(pasteAction);
3500
- if (pasteAction.futureFocusBlock) {
3501
- this.switchCaretPositionToNextElement(pasteAction.futureFocusBlock, pasteAction.futureFocusAtEnd);
3502
- }
3503
- }
3504
- else {
3505
- // No resolvable empty block: fall back to appending at the root so the
3506
- // pasted content is preserved instead of being discarded.
3507
- this.insertBlocksToRoot(blocks);
3690
+ const contentStep = {
3691
+ target: currentBlock,
3692
+ action: new PasteContentAction(blocks, cursorNode, 0, rteRange),
3693
+ };
3694
+ // eslint-disable-next-line jsdoc/require-jsdoc
3695
+ const caretStep = (context) => {
3696
+ const pasteAction = context.getAction(ModifyContentActionType.PASTE_CONTENT);
3697
+ if (pasteAction && pasteAction.futureFocusBlock) {
3698
+ return this.caretToBlockOperation(pasteAction.futureFocusBlock, pasteAction.futureFocusAtEnd);
3699
+ }
3700
+ };
3701
+ return [contentStep, caretStep];
3508
3702
  }
3703
+ // No resolvable empty block: fall back to appending at the root so the
3704
+ // pasted content is preserved instead of being discarded.
3705
+ return this.insertBlocksToRoot(blocks);
3509
3706
  }
3510
3707
  /**
3511
3708
  * Format and parse elements from user paste with simple style preservation.
3512
3709
  *
3513
3710
  * @param {InputEvent} event - Paste event.
3711
+ * @param {RTERange} [currentRange] - Optional range used to resolve the paste location.
3514
3712
  * @returns {RTEContentBlock[]} - RTEContentBlock.
3515
3713
  */
3516
- parsePastedElements(event) {
3714
+ parsePastedElements(event, currentRange) {
3715
+ var _a;
3517
3716
  const payload = this.getPastePayload(event);
3717
+ if (payload.type === RTE_PASTE_MODE_PLAIN) {
3718
+ // Native tables encode their layout as tab-separated cells (one row per line) in
3719
+ // text/plain, so pasting that verbatim keeps the rows/columns. Non-native tables (rich text
3720
+ // editor tables) put a blank line between cells in text/plain, so they derive from HTML
3721
+ // instead: htmlToPlainText puts each cell on its own line with no gaps while keeping in-cell breaks.
3722
+ let plainText;
3723
+ let hasEncodedWhitespace = (_a = payload.hasEncodedWhitespace) !== null && _a !== void 0 ? _a : false;
3724
+ if (payload.html &&
3725
+ payload.text &&
3726
+ payload.text.includes('\t') &&
3727
+ htmlContainsTable(payload.html)) {
3728
+ plainText = payload.text;
3729
+ }
3730
+ else if (payload.html && htmlContainsTable(payload.html)) {
3731
+ plainText = this.extractPlainTextFromHtml(payload.html, true);
3732
+ hasEncodedWhitespace = true;
3733
+ }
3734
+ else {
3735
+ plainText = '';
3736
+ if (payload.text) {
3737
+ plainText = payload.text;
3738
+ }
3739
+ else if (payload.html) {
3740
+ plainText = this.extractPlainTextFromHtml(payload.html, true);
3741
+ hasEncodedWhitespace = true;
3742
+ }
3743
+ }
3744
+ const styleSource = (currentRange === null || currentRange === void 0 ? void 0 : currentRange.startNode) instanceof RTETextNode ? currentRange.startNode : undefined;
3745
+ return this.buildPlainTextParagraph(plainText, styleSource, hasEncodedWhitespace);
3746
+ }
3518
3747
  let pastedHTML = payload.html || '';
3519
3748
  if (!pastedHTML) {
3520
3749
  pastedHTML = this.parsePlainText(payload.text || '');
@@ -3552,16 +3781,21 @@ class InsertPasteHandler extends BaseHandler {
3552
3781
  return resultBlocks;
3553
3782
  }
3554
3783
  /**
3555
- * Extracts readable plain text from clipboard HTML.
3784
+ * Extracts plain text from HTML when clipboard lacks `text/plain`.
3556
3785
  *
3557
3786
  * @param {string} html - Clipboard text/html payload.
3787
+ * @param {boolean} keepPreservedWhitespaceMarkers - Keep code-block indentation as sentinels so
3788
+ * the plain-mode boundary collapse in `toPlainPasteLines` does not strip it (that helper decodes
3789
+ * the sentinels). Must stay `false` for the rich path, which feeds `parsePlainText` directly.
3558
3790
  * @returns {string} - Plain text extracted from HTML.
3559
3791
  */
3560
- extractPlainTextFromHtml(html) {
3792
+ extractPlainTextFromHtml(html, keepPreservedWhitespaceMarkers = false) {
3561
3793
  // Preserve inline styles before parsing to avoid style-src-attr CSP violations.
3562
3794
  const safeHtml = StylePreservator.preserve(html).getProcessedHtml();
3563
- const parsedDoc = new DOMParser().parseFromString(safeHtml, 'text/html');
3564
- return (parsedDoc.body.textContent || '').replace(/\r\n?/g, '\n');
3795
+ return htmlToPlainText(safeHtml, {
3796
+ preserveBoundaryBlankLines: true,
3797
+ keepPreservedWhitespaceMarkers,
3798
+ });
3565
3799
  }
3566
3800
  /**
3567
3801
  * Builds plain-text paragraph blocks when element strategy parsing returns no output.
@@ -3570,7 +3804,7 @@ class InsertPasteHandler extends BaseHandler {
3570
3804
  * @returns {RTEContentBlock[]} Fallback text blocks.
3571
3805
  */
3572
3806
  buildPlainTextFallbackBlocks(text) {
3573
- return text.split('\n').map((line) => {
3807
+ return normalizePlainTextLines(text).map((line) => {
3574
3808
  const paragraph = new RTETextBlock(generateUUID(), 'paragraph');
3575
3809
  const textNode = new RTETextNode(`${paragraph.id}1`, line, paragraph);
3576
3810
  paragraph.apply(new AppendChildrenAction([textNode]));
@@ -3578,21 +3812,66 @@ class InsertPasteHandler extends BaseHandler {
3578
3812
  });
3579
3813
  }
3580
3814
  /**
3581
- * Moves the caret to a block element in a rich text editor after paste.
3815
+ * Builds plain-text paragraphs by splitting on `\n`.
3816
+ *
3817
+ * Shares `toPlainPasteLines` with `PlainPasteProcessingStrategy` so both
3818
+ * representations of plain-mode content (HTML and RTE nodes) agree on line
3819
+ * boundaries and boundary whitespace.
3820
+ *
3821
+ * @param {string} text - Plain text clipboard content.
3822
+ * @param {RTETextNode} [styleSource] - Optional style to preserve in all nodes.
3823
+ * @param {boolean} decodeEncodedWhitespace - Decode HTML-derived whitespace markers.
3824
+ * @returns {RTEContentBlock[]} Paragraph-per-line blocks.
3825
+ */
3826
+ buildPlainTextParagraph(text, styleSource, decodeEncodedWhitespace = false) {
3827
+ const lines = toPlainPasteLines(text, decodeEncodedWhitespace);
3828
+ return lines.map((line, lineIndex) => {
3829
+ const paragraph = new RTETextBlock(generateUUID(), 'paragraph');
3830
+ // Always attach a text node (empty for blank lines) so empty paragraphs
3831
+ // render with a zero-width space and keep their visible line height,
3832
+ // instead of collapsing to an invisible zero-height `<p></p>`.
3833
+ const node = this.createPlainTextNode(paragraph, lineIndex, line, styleSource);
3834
+ paragraph.apply(new AppendChildrenAction([node]));
3835
+ return paragraph;
3836
+ });
3837
+ }
3838
+ /**
3839
+ * Creates a text node for plain paste; optionally inherits style from source node.
3840
+ *
3841
+ * @param {RTETextBlock} paragraph - Parent paragraph.
3842
+ * @param {number} index - Character index for node ID generation.
3843
+ * @param {string} text - Text content.
3844
+ * @param {RTETextNode} [styleSource] - Optional style to inherit.
3845
+ * @returns {RTETextNode} Created text node.
3846
+ */
3847
+ createPlainTextNode(paragraph, index, text, styleSource) {
3848
+ const node = styleSource
3849
+ ? styleSource.cloneWithText(text)
3850
+ : new RTETextNode(`${paragraph.id}-${index}`, text, paragraph);
3851
+ node.parent = paragraph;
3852
+ return node;
3853
+ }
3854
+ /**
3855
+ * Builds the caret operation that moves onto a block element in a rich text editor after paste.
3582
3856
  *
3583
3857
  * @param {RTEBlock} newBlock - Block element to move the caret to.
3584
3858
  * @param {boolean} atEnd - When true, places the caret after the last character of the block's last node; otherwise at offset 0 of the first node.
3859
+ * @returns {CompositionOperation | void} The caret operation, or nothing when the block has no children.
3585
3860
  */
3586
- switchCaretPositionToNextElement(newBlock, atEnd = false) {
3861
+ caretToBlockOperation(newBlock, atEnd = false) {
3587
3862
  var _a, _b;
3588
3863
  if (newBlock && newBlock.children) {
3589
3864
  if (atEnd) {
3590
3865
  const lastNode = newBlock.children[newBlock.children.length - 1];
3591
- this.selectionController.enqueueSelectionRangeFutureState(lastNode, (_b = (_a = lastNode.text) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0);
3592
- }
3593
- else {
3594
- this.selectionController.enqueueSelectionRangeFutureState(newBlock.children[0], 0);
3866
+ return {
3867
+ target: this.currentState,
3868
+ action: new UpdateCursorPositionAction(lastNode, (_b = (_a = lastNode.text) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0),
3869
+ };
3595
3870
  }
3871
+ return {
3872
+ target: this.currentState,
3873
+ action: new UpdateCursorPositionAction(newBlock.children[0], 0),
3874
+ };
3596
3875
  }
3597
3876
  }
3598
3877
  /**
@@ -3812,6 +4091,7 @@ class InsertPasteHandler extends BaseHandler {
3812
4091
  html: event.dataTransfer.getData('text/html') || eventPayload.html || '',
3813
4092
  text: event.dataTransfer.getData('text/plain') || eventPayload.text || '',
3814
4093
  type: event.dataTransfer.getData(RTE_PASTE_MODE_DATA_TYPE) || '',
4094
+ hasEncodedWhitespace: event.dataTransfer.getData(RTE_PRESERVED_WHITESPACE_DATA_TYPE) === 'true',
3815
4095
  };
3816
4096
  }
3817
4097
  }
@@ -4136,6 +4416,8 @@ class UserInputController extends VegaSlimmer {
4136
4416
  };
4137
4417
  /**
4138
4418
  * When a user performs an input action within the editable element, this function is triggered.
4419
+ * Each handler owns its own `flushOptions` on `BaseHandler`, so the value update flows through
4420
+ * the shared flush-changes action pipeline without this method having to construct or forward it.
4139
4421
  *
4140
4422
  * @param {InputEvent} e the before input event object
4141
4423
  */
@@ -4149,41 +4431,26 @@ class UserInputController extends VegaSlimmer {
4149
4431
  return;
4150
4432
  }
4151
4433
  this.insertCompositionTextController.removeObserver();
4152
- let updateFlag = false;
4153
- let updateSource = RTEUpdateSource.Default;
4154
4434
  switch (inputType) {
4155
4435
  case 'insertParagraph':
4156
- updateFlag = true;
4157
4436
  this.insertParagraphHandler.execute(this.value, this.selectionController, this.host, e);
4158
4437
  break;
4159
4438
  case 'insertText':
4160
- updateFlag = true;
4161
- updateSource =
4162
- e[RTE_UPDATE_SOURCE_KEY] === RTEUpdateSource.Composition
4163
- ? RTEUpdateSource.Composition
4164
- : RTEUpdateSource.Default;
4165
4439
  this.insertTextHandler.execute(this.value, this.selectionController, this.host, e);
4166
4440
  break;
4167
4441
  case 'insertLineBreak':
4168
- updateFlag = true;
4169
4442
  this.insertLineBreakHandler.execute(this.value, this.selectionController, this.host, e);
4170
4443
  break;
4171
4444
  case 'deleteContentForward':
4172
- updateFlag = true;
4173
4445
  this.forwardDeleteContentHandler.execute(this.value, this.selectionController, this.host, e);
4174
4446
  break;
4175
4447
  case 'deleteContentBackward':
4176
- updateFlag = true;
4177
4448
  this.backwardDeleteContentHandler.execute(this.value, this.selectionController, this.host, e);
4178
4449
  break;
4179
4450
  case 'insertFromPaste':
4180
- updateFlag = true;
4181
4451
  this.insertPasteHandler.execute(this.value, this.selectionController, this.host, e);
4182
4452
  break;
4183
4453
  }
4184
- if (updateFlag) {
4185
- void this.valueController.flushChanges(this.value, true, updateSource);
4186
- }
4187
4454
  };
4188
4455
  }
4189
4456
  /**