@heartlandone/vega 2.94.0 → 2.96.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 (381) hide show
  1. package/dist/cjs/{app-globals-d05c3410.js → app-globals-38afea36.js} +7 -7
  2. package/dist/cjs/{child-nodes-event-prevent-slimmer-e67ee84c.js → child-nodes-event-prevent-slimmer-e0ac8467.js} +1 -1
  3. package/dist/cjs/{code-block-493c7ce7.js → code-block-4126dc3b.js} +1501 -55
  4. package/dist/cjs/{component-value-history-controller-slimmer.abstract-ab21fcbf.js → component-value-history-controller-slimmer.abstract-38ba956e.js} +2 -2
  5. package/dist/cjs/{content-state-fc34a814.js → content-state-50e8a03c.js} +142 -580
  6. package/dist/cjs/{element-appender-slimmer-1d6323c2.js → element-appender-slimmer-7773fdab.js} +115 -0
  7. package/dist/cjs/{event-emit-slimmer-d234a619.js → event-emit-slimmer-34aa195e.js} +1 -1
  8. package/dist/cjs/{image-annotation-action-7c4cd316.js → image-annotation-action-89363de8.js} +2 -2
  9. package/dist/cjs/{image-extension-30a7c10f.js → image-extension-c881c454.js} +2 -2
  10. package/dist/cjs/index.cjs.js +11 -11
  11. package/dist/cjs/{internal-vega-event-manager-13c4012b.js → internal-vega-event-manager-7003c84a.js} +10 -2
  12. package/dist/cjs/{link-extension-92a63cb7.js → link-extension-b7f99a52.js} +2 -2
  13. package/dist/cjs/loader.cjs.js +9 -9
  14. package/dist/cjs/{public-rules-9e1ea1d9.js → public-rules-72894208.js} +3 -3
  15. package/dist/cjs/{range-30219330.js → range-95d41dea.js} +1 -1
  16. package/dist/cjs/{rich-text-editor-required-rule-23bf7485.js → rich-text-editor-required-rule-4d6d2493.js} +1 -1
  17. package/dist/cjs/shared-backdrop-manager-71e54fdb.js +199 -0
  18. package/dist/cjs/{split-cell-operation-43752212.js → split-cell-operation-70be116d.js} +2 -2
  19. package/dist/cjs/{token-extension-ea891d54.js → token-extension-eb828948.js} +36 -12
  20. package/dist/cjs/vega-accordion.cjs.entry.js +2 -2
  21. package/dist/cjs/vega-app-footer.cjs.entry.js +2 -2
  22. package/dist/cjs/vega-app-header-button.cjs.entry.js +3 -3
  23. package/dist/cjs/vega-banner.cjs.entry.js +2 -2
  24. package/dist/cjs/vega-breadcrumb.cjs.entry.js +3 -3
  25. package/dist/cjs/vega-button-circle.cjs.entry.js +3 -3
  26. package/dist/cjs/vega-button-group_2.cjs.entry.js +3 -3
  27. package/dist/cjs/vega-button-link.cjs.entry.js +3 -3
  28. package/dist/cjs/vega-button.cjs.entry.js +3 -3
  29. package/dist/cjs/vega-calendar_5.cjs.entry.js +3 -3
  30. package/dist/cjs/vega-carousel.cjs.entry.js +2 -2
  31. package/dist/cjs/vega-checkbox_2.cjs.entry.js +3 -3
  32. package/dist/cjs/vega-chip.cjs.entry.js +3 -3
  33. package/dist/cjs/vega-code-block.cjs.entry.js +6 -6
  34. package/dist/cjs/vega-color-picker.cjs.entry.js +2 -2
  35. package/dist/cjs/vega-color-swatch-picker.cjs.entry.js +3 -3
  36. package/dist/cjs/vega-color-swatch.cjs.entry.js +2 -2
  37. package/dist/cjs/vega-combo-box.cjs.entry.js +22 -4
  38. package/dist/cjs/vega-date-picker_2.cjs.entry.js +4 -4
  39. package/dist/cjs/vega-dialog_2.cjs.entry.js +160 -70
  40. package/dist/cjs/vega-dropdown_5.cjs.entry.js +41 -13
  41. package/dist/cjs/vega-env-manager-23b8b23c.js +2 -2
  42. package/dist/cjs/vega-field-label.cjs.entry.js +2 -2
  43. package/dist/cjs/vega-file-uploader.cjs.entry.js +2 -2
  44. package/dist/cjs/vega-form.cjs.entry.js +3 -3
  45. package/dist/cjs/vega-image-uploader.cjs.entry.js +3 -3
  46. package/dist/cjs/vega-input-credit-card.cjs.entry.js +3 -3
  47. package/dist/cjs/vega-input-numeric.cjs.entry.js +3 -3
  48. package/dist/cjs/vega-input-passcode.cjs.entry.js +3 -3
  49. package/dist/cjs/vega-input-phone-number.cjs.entry.js +3 -3
  50. package/dist/cjs/vega-input-range.cjs.entry.js +3 -3
  51. package/dist/cjs/vega-input-select.cjs.entry.js +54 -5
  52. package/dist/cjs/vega-input.cjs.entry.js +2 -2
  53. package/dist/cjs/vega-item-toggle.cjs.entry.js +2 -2
  54. package/dist/cjs/vega-left-nav_5.cjs.entry.js +32 -193
  55. package/dist/cjs/vega-pagination-page-selector-mobile.cjs.entry.js +2 -2
  56. package/dist/cjs/vega-pagination.cjs.entry.js +3 -3
  57. package/dist/cjs/vega-popover_2.cjs.entry.js +3 -3
  58. package/dist/cjs/vega-progress-tracker_2.cjs.entry.js +13 -3
  59. package/dist/cjs/vega-radio_2.cjs.entry.js +3 -3
  60. package/dist/cjs/vega-rich-text-content.cjs.entry.js +58 -9
  61. package/dist/cjs/vega-rich-text-editor_4.cjs.entry.js +611 -93
  62. package/dist/cjs/vega-rich-text-find-replace-panel.cjs.entry.js +2 -2
  63. package/dist/cjs/vega-rich-text-special-characters-panel.cjs.entry.js +2 -2
  64. package/dist/cjs/vega-rich-text-table-properties_3.cjs.entry.js +5 -5
  65. package/dist/cjs/vega-section-title.cjs.entry.js +896 -14
  66. package/dist/cjs/vega-segment-control.cjs.entry.js +2 -2
  67. package/dist/cjs/vega-selection-chip_2.cjs.entry.js +3 -3
  68. package/dist/cjs/vega-selection-tile_2.cjs.entry.js +3 -3
  69. package/dist/cjs/vega-sidenav_3.cjs.entry.js +2 -2
  70. package/dist/cjs/vega-signature-capture.cjs.entry.js +2 -2
  71. package/dist/cjs/vega-stepper.cjs.entry.js +3 -3
  72. package/dist/cjs/vega-tab-group_2.cjs.entry.js +3 -3
  73. package/dist/cjs/vega-table_11.cjs.entry.js +3 -3
  74. package/dist/cjs/vega-textarea.cjs.entry.js +3 -3
  75. package/dist/cjs/vega-time-picker_2.cjs.entry.js +4 -4
  76. package/dist/cjs/vega-toggle-switch.cjs.entry.js +2 -2
  77. package/dist/cjs/vega-tooltip_2.cjs.entry.js +1 -1
  78. package/dist/cjs/vega.cjs.js +9 -9
  79. package/dist/collection/components/vega-combo-box/slimmers/renderers/vega-combo-box-dropdown-renderer.js +5 -1
  80. package/dist/collection/components/vega-combo-box/vega-combo-box.js +52 -1
  81. package/dist/collection/components/vega-dialog/vega-dialog.js +1 -1
  82. package/dist/collection/components/vega-dropdown/slimmers/controllers/vega-dropdown-render-mode-controller.js +7 -6
  83. package/dist/collection/components/vega-dropdown/vega-dropdown.js +36 -8
  84. package/dist/collection/components/vega-input-select/slimmers/controllers/vega-input-select-dropdown-controller.js +11 -1
  85. package/dist/collection/components/vega-input-select/slimmers/controllers/vega-input-select-items-slot-controler.js +23 -2
  86. package/dist/collection/components/vega-input-select/slimmers/renderers/vega-input-select-dropdown-renderer.js +4 -0
  87. package/dist/collection/components/vega-input-select/vega-input-select.js +53 -2
  88. package/dist/collection/components/vega-modal/slimmers/controllers/vega-modal-backdrop-manager.js +141 -0
  89. package/dist/collection/components/vega-modal/slimmers/controllers/vega-modal-open-state-controller.js +10 -17
  90. package/dist/collection/components/vega-modal/slimmers/controllers/vega-modal-z-index-controller.js +2 -2
  91. package/dist/collection/components/vega-modal/slimmers/renderers/vega-modal-renderer.js +3 -2
  92. package/dist/collection/components/vega-modal/vega-modal.js +77 -8
  93. package/dist/collection/components/vega-progress-tracker/slimmers/controllers/vega-progress-tracker-current-steps-controller.js +7 -0
  94. package/dist/collection/components/vega-progress-tracker/vega-progress-tracker.js +6 -0
  95. package/dist/collection/components/vega-rich-text-content/vega-rich-text-content.css +4 -0
  96. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-delete-node-content-strategy.js +29 -0
  97. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-delete-text-or-decorator-node-strategy.js +10 -1
  98. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-transform-to-list-strategy.js +8 -3
  99. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.js +60 -0
  100. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-item-replace-nest-list-strategy.js +36 -4
  101. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.js +27 -0
  102. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.js +74 -0
  103. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.js +81 -1
  104. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.js +30 -0
  105. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.js +160 -9
  106. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.js +376 -10
  107. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.js +104 -0
  108. package/dist/collection/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.js +2 -0
  109. package/dist/collection/components/vega-rich-text-editor/dto/actions/nest-list-items-action.js +12 -0
  110. package/dist/collection/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.js +12 -0
  111. package/dist/collection/components/vega-rich-text-editor/dto/annotations/list-annotation.js +12 -0
  112. package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-block.js +10 -1
  113. package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-item-block.js +11 -3
  114. package/dist/collection/components/vega-rich-text-editor/dto/content-state.js +7 -1
  115. package/dist/collection/components/vega-rich-text-editor/dto/filter-styles-strategies/list-block/list-block-filter-styles-strategy.js +8 -4
  116. package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.js +34 -1
  117. package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.js +20 -3
  118. package/dist/collection/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.js +25 -1
  119. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/element-to-dto-strategy/li-to-rte-list-item-block-strategy.js +2 -0
  120. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/abstract-delete-content-handler.js +29 -0
  121. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.js +30 -1
  122. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.js +204 -0
  123. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.js +42 -0
  124. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.js +34 -0
  125. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.js +180 -0
  126. package/dist/collection/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.js +54 -0
  127. package/dist/collection/components/vega-section-title/slimmers/renderers/vega-section-title-renderer.js +4 -4
  128. package/dist/collection/components/vega-section-title/vega-section-title.js +18 -2
  129. package/dist/collection/helpers/a11y-tree/a11y-node-dto.js +210 -0
  130. package/dist/collection/helpers/a11y-tree/a11y-tree-applier.js +189 -0
  131. package/dist/collection/helpers/a11y-tree/a11y-tree.types.js +48 -0
  132. package/dist/collection/helpers/a11y-tree/strategies/baseline-strategy.js +78 -0
  133. package/dist/collection/helpers/a11y-tree/strategies/firefox-nvda-strategy.js +56 -0
  134. package/dist/collection/helpers/a11y-tree/strategies/webkit-voiceover-strategy.js +140 -0
  135. package/dist/collection/helpers/a11y-tree/strategy-resolver.js +172 -0
  136. package/dist/collection/helpers/backdrop/shared-backdrop-manager.js +32 -1
  137. package/dist/collection/helpers/event-manager/event-id/component-event-id-map.js +11 -3
  138. package/dist/collection/helpers/slimmers/a11y-tree-slimmer.js +54 -0
  139. package/dist/collection/helpers/slimmers/element-appender/element-appender-slimmer.js +29 -0
  140. package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.js +70 -0
  141. package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.js +1 -0
  142. package/dist/collection/helpers/ui/element-appender.js +16 -0
  143. package/dist/esm/{app-globals-f2336686.js → app-globals-d7b651c1.js} +7 -7
  144. package/dist/esm/{child-nodes-event-prevent-slimmer-96c14f5a.js → child-nodes-event-prevent-slimmer-82626871.js} +1 -1
  145. package/dist/esm/{code-block-e12588fe.js → code-block-0a88b481.js} +1495 -51
  146. package/dist/esm/{component-value-history-controller-slimmer.abstract-4e8eb313.js → component-value-history-controller-slimmer.abstract-6846edfa.js} +2 -2
  147. package/dist/esm/{content-state-8032467a.js → content-state-79ca99e5.js} +105 -541
  148. package/dist/esm/{element-appender-slimmer-7fcb944b.js → element-appender-slimmer-73ad10ae.js} +115 -0
  149. package/dist/esm/{event-emit-slimmer-db4a82e0.js → event-emit-slimmer-2452278f.js} +1 -1
  150. package/dist/esm/{image-annotation-action-b3b6c308.js → image-annotation-action-bb299ef1.js} +3 -3
  151. package/dist/esm/{image-extension-b6c7e4a7.js → image-extension-48a96f98.js} +2 -2
  152. package/dist/esm/index.js +10 -10
  153. package/dist/esm/{internal-vega-event-manager-48690e5b.js → internal-vega-event-manager-2ecc9186.js} +11 -3
  154. package/dist/esm/{link-extension-97fcb8fb.js → link-extension-09534514.js} +2 -2
  155. package/dist/esm/loader.js +10 -10
  156. package/dist/esm/{public-rules-c06f0d2a.js → public-rules-5eb03ef0.js} +3 -3
  157. package/dist/esm/{range-e999837f.js → range-d4deb7df.js} +1 -1
  158. package/dist/esm/{rich-text-editor-required-rule-71f8ee98.js → rich-text-editor-required-rule-5bbbce23.js} +1 -1
  159. package/dist/esm/shared-backdrop-manager-a7c63838.js +197 -0
  160. package/dist/esm/{split-cell-operation-359f8082.js → split-cell-operation-7f3058ad.js} +2 -2
  161. package/dist/esm/{token-extension-9896879b.js → token-extension-40c32bcc.js} +32 -8
  162. package/dist/esm/vega-accordion.entry.js +3 -3
  163. package/dist/esm/vega-app-footer.entry.js +3 -3
  164. package/dist/esm/vega-app-header-button.entry.js +4 -4
  165. package/dist/esm/vega-banner.entry.js +3 -3
  166. package/dist/esm/vega-breadcrumb.entry.js +4 -4
  167. package/dist/esm/vega-button-circle.entry.js +4 -4
  168. package/dist/esm/vega-button-group_2.entry.js +4 -4
  169. package/dist/esm/vega-button-link.entry.js +4 -4
  170. package/dist/esm/vega-button.entry.js +4 -4
  171. package/dist/esm/vega-calendar_5.entry.js +4 -4
  172. package/dist/esm/vega-carousel.entry.js +3 -3
  173. package/dist/esm/vega-checkbox_2.entry.js +4 -4
  174. package/dist/esm/vega-chip.entry.js +4 -4
  175. package/dist/esm/vega-code-block.entry.js +7 -7
  176. package/dist/esm/vega-color-picker.entry.js +3 -3
  177. package/dist/esm/vega-color-swatch-picker.entry.js +4 -4
  178. package/dist/esm/vega-color-swatch.entry.js +3 -3
  179. package/dist/esm/vega-combo-box.entry.js +23 -5
  180. package/dist/esm/vega-date-picker_2.entry.js +5 -5
  181. package/dist/esm/vega-dialog_2.entry.js +161 -71
  182. package/dist/esm/vega-dropdown_5.entry.js +42 -14
  183. package/dist/esm/vega-env-manager-8f8dc473.js +2 -2
  184. package/dist/esm/{vega-event-id-270fe47e.js → vega-event-id-f55f6977.js} +1 -1
  185. package/dist/esm/vega-field-label.entry.js +3 -3
  186. package/dist/esm/vega-file-uploader.entry.js +3 -3
  187. package/dist/esm/vega-form.entry.js +4 -4
  188. package/dist/esm/vega-image-uploader.entry.js +4 -4
  189. package/dist/esm/vega-input-credit-card.entry.js +4 -4
  190. package/dist/esm/vega-input-numeric.entry.js +4 -4
  191. package/dist/esm/vega-input-passcode.entry.js +4 -4
  192. package/dist/esm/vega-input-phone-number.entry.js +4 -4
  193. package/dist/esm/vega-input-range.entry.js +4 -4
  194. package/dist/esm/vega-input-select.entry.js +55 -6
  195. package/dist/esm/vega-input.entry.js +3 -3
  196. package/dist/esm/vega-item-toggle.entry.js +3 -3
  197. package/dist/esm/vega-left-nav_5.entry.js +32 -193
  198. package/dist/esm/vega-page-notification_2.entry.js +1 -1
  199. package/dist/esm/vega-pagination-page-selector-mobile.entry.js +3 -3
  200. package/dist/esm/vega-pagination-page-size-selector-mobile.entry.js +1 -1
  201. package/dist/esm/vega-pagination.entry.js +4 -4
  202. package/dist/esm/vega-popover_2.entry.js +4 -4
  203. package/dist/esm/vega-progress-tracker_2.entry.js +14 -4
  204. package/dist/esm/vega-radio_2.entry.js +4 -4
  205. package/dist/esm/vega-rich-text-content.entry.js +59 -10
  206. package/dist/esm/vega-rich-text-editor_4.entry.js +608 -90
  207. package/dist/esm/vega-rich-text-find-replace-panel.entry.js +3 -3
  208. package/dist/esm/vega-rich-text-special-characters-panel.entry.js +3 -3
  209. package/dist/esm/vega-rich-text-table-properties_3.entry.js +6 -6
  210. package/dist/esm/vega-section-title.entry.js +897 -15
  211. package/dist/esm/vega-segment-control.entry.js +3 -3
  212. package/dist/esm/vega-selection-chip_2.entry.js +4 -4
  213. package/dist/esm/vega-selection-tile_2.entry.js +4 -4
  214. package/dist/esm/vega-sidenav_3.entry.js +3 -3
  215. package/dist/esm/vega-signature-capture.entry.js +3 -3
  216. package/dist/esm/vega-stepper.entry.js +4 -4
  217. package/dist/esm/vega-tab-group_2.entry.js +4 -4
  218. package/dist/esm/vega-table_11.entry.js +4 -4
  219. package/dist/esm/vega-textarea.entry.js +4 -4
  220. package/dist/esm/vega-time-picker_2.entry.js +5 -5
  221. package/dist/esm/vega-toggle-switch.entry.js +3 -3
  222. package/dist/esm/vega-tooltip_2.entry.js +1 -1
  223. package/dist/esm/vega.js +10 -10
  224. package/dist/sri/vega-sri-manifest.json +272 -268
  225. package/dist/types/components/vega-combo-box/slimmers/renderers/vega-combo-box-dropdown-renderer.d.ts +1 -0
  226. package/dist/types/components/vega-combo-box/vega-combo-box.d.ts +21 -0
  227. package/dist/types/components/vega-dropdown/slimmers/controllers/vega-dropdown-render-mode-controller.d.ts +2 -1
  228. package/dist/types/components/vega-dropdown/types.d.ts +2 -2
  229. package/dist/types/components/vega-dropdown/vega-dropdown.d.ts +36 -9
  230. package/dist/types/components/vega-input-select/slimmers/controllers/vega-input-select-dropdown-controller.d.ts +2 -0
  231. package/dist/types/components/vega-input-select/slimmers/controllers/vega-input-select-items-slot-controler.d.ts +10 -0
  232. package/dist/types/components/vega-input-select/types.d.ts +1 -0
  233. package/dist/types/components/vega-input-select/vega-input-select.d.ts +21 -0
  234. package/dist/types/components/vega-modal/slimmers/controllers/vega-modal-backdrop-manager.d.ts +66 -0
  235. package/dist/types/components/vega-modal/slimmers/controllers/vega-modal-open-state-controller.d.ts +1 -5
  236. package/dist/types/components/vega-modal/slimmers/controllers/vega-modal-z-index-controller.d.ts +1 -1
  237. package/dist/types/components/vega-modal/slimmers/renderers/vega-modal-renderer.d.ts +1 -1
  238. package/dist/types/components/vega-modal/vega-modal.d.ts +34 -6
  239. package/dist/types/components/vega-progress-tracker/slimmers/controllers/vega-progress-tracker-current-steps-controller.d.ts +2 -0
  240. package/dist/types/components/vega-progress-tracker/vega-progress-tracker.d.ts +1 -0
  241. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.d.ts +36 -0
  242. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-item-replace-nest-list-strategy.d.ts +14 -2
  243. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.d.ts +22 -0
  244. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.d.ts +21 -0
  245. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.d.ts +14 -0
  246. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.d.ts +15 -0
  247. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.d.ts +30 -3
  248. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.d.ts +99 -3
  249. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.d.ts +22 -0
  250. package/dist/types/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.d.ts +2 -0
  251. package/dist/types/components/vega-rich-text-editor/dto/actions/nest-list-items-action.d.ts +11 -0
  252. package/dist/types/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.d.ts +11 -0
  253. package/dist/types/components/vega-rich-text-editor/dto/annotations/list-annotation.d.ts +8 -0
  254. package/dist/types/components/vega-rich-text-editor/dto/blocks/list-block.d.ts +6 -1
  255. package/dist/types/components/vega-rich-text-editor/dto/blocks/list-item-block.d.ts +5 -1
  256. package/dist/types/components/vega-rich-text-editor/dto/content-state.d.ts +2 -2
  257. package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.d.ts +2 -0
  258. package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.d.ts +8 -0
  259. package/dist/types/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.d.ts +18 -0
  260. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.d.ts +8 -0
  261. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.d.ts +99 -0
  262. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.d.ts +15 -0
  263. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.d.ts +15 -0
  264. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.d.ts +73 -0
  265. package/dist/types/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.d.ts +41 -0
  266. package/dist/types/components/vega-section-title/vega-section-title.d.ts +9 -0
  267. package/dist/types/components.d.ts +42 -8
  268. package/dist/types/helpers/a11y-tree/a11y-node-dto.d.ts +173 -0
  269. package/dist/types/helpers/a11y-tree/a11y-tree-applier.d.ts +28 -0
  270. package/dist/types/helpers/a11y-tree/a11y-tree.types.d.ts +137 -0
  271. package/dist/types/helpers/a11y-tree/strategies/baseline-strategy.d.ts +18 -0
  272. package/dist/types/helpers/a11y-tree/strategies/firefox-nvda-strategy.d.ts +16 -0
  273. package/dist/types/helpers/a11y-tree/strategies/webkit-voiceover-strategy.d.ts +23 -0
  274. package/dist/types/helpers/a11y-tree/strategy-resolver.d.ts +59 -0
  275. package/dist/types/helpers/backdrop/shared-backdrop-manager.d.ts +16 -0
  276. package/dist/types/helpers/slimmers/a11y-tree-slimmer.d.ts +49 -0
  277. package/dist/types/helpers/slimmers/element-appender/element-appender-slimmer.d.ts +9 -0
  278. package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.d.ts +37 -0
  279. package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.d.ts +56 -0
  280. package/dist/types/helpers/ui/element-appender.d.ts +7 -0
  281. package/dist/vega/index.esm.js +1 -1
  282. package/dist/vega/{p-3e8baeac.entry.js → p-0512308f.entry.js} +1 -1
  283. package/dist/vega/{p-46fe3154.entry.js → p-1d8312d3.entry.js} +1 -1
  284. package/dist/vega/{p-f5d7b89f.entry.js → p-1dfbc542.entry.js} +1 -1
  285. package/dist/vega/{p-fbd3be00.entry.js → p-200c8914.entry.js} +1 -1
  286. package/dist/vega/{p-e235020b.entry.js → p-22cc174e.entry.js} +1 -1
  287. package/dist/vega/{p-b1ff70bf.js → p-2c737fc8.js} +1 -1
  288. package/dist/vega/{p-782eb312.entry.js → p-2d77ae73.entry.js} +1 -1
  289. package/dist/vega/{p-cb90163a.entry.js → p-2d8d4d5b.entry.js} +1 -1
  290. package/dist/vega/{p-f651df3b.entry.js → p-2df5d59b.entry.js} +1 -1
  291. package/dist/vega/p-31216140.js +1 -0
  292. package/dist/vega/{p-f7e459cd.js → p-312d8205.js} +1 -1
  293. package/dist/vega/{p-a7209700.js → p-3345d903.js} +1 -1
  294. package/dist/vega/{p-44439ecc.entry.js → p-36d2df7a.entry.js} +1 -1
  295. package/dist/vega/{p-02355de8.js → p-3c23ec90.js} +1 -1
  296. package/dist/vega/{p-2bf17505.entry.js → p-3d6f761a.entry.js} +1 -1
  297. package/dist/vega/p-4151f53a.entry.js +1 -0
  298. package/dist/vega/{p-a057285e.entry.js → p-49e1cf4d.entry.js} +1 -1
  299. package/dist/vega/{p-698fbd73.js → p-5447a8e8.js} +1 -1
  300. package/dist/vega/p-55e0014a.js +3 -0
  301. package/dist/vega/{p-45e8424a.entry.js → p-56d19601.entry.js} +1 -1
  302. package/dist/vega/{p-addbca58.entry.js → p-5924adae.entry.js} +1 -1
  303. package/dist/vega/{p-9dca874d.entry.js → p-5e4517eb.entry.js} +1 -1
  304. package/dist/vega/p-5f377954.js +1 -1
  305. package/dist/vega/p-65fee02f.entry.js +1 -0
  306. package/dist/vega/{p-140616fe.js → p-66647244.js} +1 -1
  307. package/dist/vega/{p-62d6e063.entry.js → p-6680ba17.entry.js} +1 -1
  308. package/dist/vega/p-6a51d720.js +1 -0
  309. package/dist/vega/{p-fe24b459.js → p-6c7b6d45.js} +1 -1
  310. package/dist/vega/{p-288d65ad.entry.js → p-6fcec7c7.entry.js} +1 -1
  311. package/dist/vega/{p-d08ffdf1.entry.js → p-74f86ff9.entry.js} +1 -1
  312. package/dist/vega/{p-6ad7144a.entry.js → p-775ecfad.entry.js} +1 -1
  313. package/dist/vega/{p-6f70a10f.entry.js → p-7950f3e2.entry.js} +1 -1
  314. package/dist/vega/{p-f246f125.entry.js → p-80b7945a.entry.js} +1 -1
  315. package/dist/vega/p-8354cff0.entry.js +1 -0
  316. package/dist/vega/{p-5db61a12.entry.js → p-841b3281.entry.js} +1 -1
  317. package/dist/vega/{p-579cdeae.js → p-84b7a775.js} +1 -1
  318. package/dist/vega/p-87e5cb56.entry.js +1 -0
  319. package/dist/vega/p-8c30a60d.js +1 -0
  320. package/dist/vega/{p-f8a29127.entry.js → p-8d96f0e8.entry.js} +1 -1
  321. package/dist/vega/{p-95913e3c.entry.js → p-91303402.entry.js} +1 -1
  322. package/dist/vega/p-96da7d30.entry.js +1 -0
  323. package/dist/vega/{p-51b68d25.js → p-9d3f69cb.js} +1 -1
  324. package/dist/vega/{p-ed103a1a.entry.js → p-9d96d83f.entry.js} +1 -1
  325. package/dist/vega/{p-6dfe2407.js → p-9f11b579.js} +1 -1
  326. package/dist/vega/p-9f201152.entry.js +1 -0
  327. package/dist/vega/{p-48ee3e24.entry.js → p-a775825e.entry.js} +1 -1
  328. package/dist/vega/{p-9d18ba7f.entry.js → p-acaff62d.entry.js} +1 -1
  329. package/dist/vega/{p-b8f8e480.entry.js → p-ae146458.entry.js} +1 -1
  330. package/dist/vega/{p-e8ee70c5.entry.js → p-b3a2ce06.entry.js} +1 -1
  331. package/dist/vega/{p-5107277d.entry.js → p-b4c26035.entry.js} +1 -1
  332. package/dist/vega/p-b63319e9.entry.js +1 -0
  333. package/dist/vega/{p-c9daabe1.entry.js → p-b660f38c.entry.js} +1 -1
  334. package/dist/vega/{p-8c083255.entry.js → p-b8c13ac9.entry.js} +1 -1
  335. package/dist/vega/p-b8ffa42f.entry.js +1 -0
  336. package/dist/vega/{p-7b57a845.entry.js → p-b9e72de2.entry.js} +1 -1
  337. package/dist/vega/{p-0af32f31.entry.js → p-bb60e381.entry.js} +1 -1
  338. package/dist/vega/p-bbad318e.entry.js +1 -0
  339. package/dist/vega/p-c0e42c03.entry.js +1 -0
  340. package/dist/vega/{p-c67b9aba.entry.js → p-c41f5684.entry.js} +1 -1
  341. package/dist/vega/{p-4fe40b76.js → p-c4564904.js} +1 -1
  342. package/dist/vega/{p-341a6b32.entry.js → p-c54b5a8f.entry.js} +1 -1
  343. package/dist/vega/p-cd1e976c.entry.js +1 -0
  344. package/dist/vega/p-d9158512.js +1 -0
  345. package/dist/vega/{p-2dc5edd0.entry.js → p-db11134b.entry.js} +1 -1
  346. package/dist/vega/{p-14559974.entry.js → p-e1737c8e.entry.js} +1 -1
  347. package/dist/vega/{p-0b311599.entry.js → p-e1b57e8f.entry.js} +1 -1
  348. package/dist/vega/{p-9f38448c.entry.js → p-e5ff77f7.entry.js} +1 -1
  349. package/dist/vega/p-e62d41ee.js +1 -0
  350. package/dist/vega/{p-6f01a71a.entry.js → p-ebe32b25.entry.js} +1 -1
  351. package/dist/vega/p-ec162599.entry.js +1 -0
  352. package/dist/vega/{p-9f7154d2.js → p-ec5dee32.js} +1 -1
  353. package/dist/vega/{p-d3a36d19.entry.js → p-ec64cc59.entry.js} +1 -1
  354. package/dist/vega/p-f29d9707.entry.js +1 -0
  355. package/dist/vega/{p-5df2d6a1.entry.js → p-f78944d7.entry.js} +1 -1
  356. package/dist/vega/{p-c9c6daa6.entry.js → p-f9bfee81.entry.js} +1 -1
  357. package/dist/vega/{p-26c7fe8b.entry.js → p-fa65956c.entry.js} +1 -1
  358. package/dist/vega/{p-f96d0503.entry.js → p-fc7e4c8a.entry.js} +1 -1
  359. package/dist/vega/{p-b39d4a88.entry.js → p-fd23c365.entry.js} +1 -1
  360. package/dist/vega/vega.esm.js +1 -1
  361. package/package.json +3 -2
  362. package/dist/collection/components/vega-modal/slimmers/controllers/vega-modal-backdrop-controller.js +0 -73
  363. package/dist/types/components/vega-modal/slimmers/controllers/vega-modal-backdrop-controller.d.ts +0 -27
  364. package/dist/vega/p-0b9c7c79.entry.js +0 -1
  365. package/dist/vega/p-0be4df0a.js +0 -1
  366. package/dist/vega/p-2364be92.entry.js +0 -1
  367. package/dist/vega/p-270697c0.entry.js +0 -1
  368. package/dist/vega/p-282b37cb.js +0 -1
  369. package/dist/vega/p-38c9d782.js +0 -1
  370. package/dist/vega/p-52c6a399.entry.js +0 -1
  371. package/dist/vega/p-73f2c3c0.entry.js +0 -1
  372. package/dist/vega/p-762ea523.entry.js +0 -1
  373. package/dist/vega/p-7a88a3d3.entry.js +0 -1
  374. package/dist/vega/p-83a16285.entry.js +0 -1
  375. package/dist/vega/p-91287214.entry.js +0 -1
  376. package/dist/vega/p-c66d2a1e.js +0 -1
  377. package/dist/vega/p-cad5222a.entry.js +0 -1
  378. package/dist/vega/p-d25ca0c3.entry.js +0 -1
  379. package/dist/vega/p-f05a193e.entry.js +0 -1
  380. package/dist/vega/p-f4da615a.js +0 -3
  381. package/dist/vega/p-f906a7bc.entry.js +0 -1
@@ -139,6 +139,8 @@ exports.ModifyContentActionType = void 0;
139
139
  ModifyContentActionType["LINE_BREAK_MULTIPLE_BLOCKS"] = "LINE_BREAK_MULTIPLE_BLOCKS";
140
140
  ModifyContentActionType["TRANSFORM_LIST_BLOCK"] = "TRANSFORM_LIST_BLOCK";
141
141
  ModifyContentActionType["TRANSFORM_PARAGRAPH_BLOCK"] = "TRANSFORM_PARAGRAPH_BLOCK";
142
+ ModifyContentActionType["NEST_LIST_ITEMS"] = "NEST_LIST_ITEMS";
143
+ ModifyContentActionType["UNNEST_LIST_ITEMS"] = "UNNEST_LIST_ITEMS";
142
144
  ModifyContentActionType["DELETE_BLOCK_CONTENT"] = "DELETE_BLOCK_CONTENT";
143
145
  ModifyContentActionType["INSERT_IMAGE_TO_BLOCK"] = "INSERT_IMAGE_TO_BLOCK";
144
146
  ModifyContentActionType["UPDATE_IMAGE_NODE_URL"] = "UPDATE_IMAGE_NODE_URL";
@@ -4261,6 +4263,37 @@ class BlockInsertImageIntoTextStrategy extends ActionHandleStrategy {
4261
4263
  }
4262
4264
  }
4263
4265
 
4266
+ /**
4267
+ * Normalize a mixed paragraph/list selection before rebuilding it as a list.
4268
+ *
4269
+ * Selected list items whose owning ancestor item is also selected remain inside
4270
+ * that ancestor's nestList instead of being emitted again as flattened siblings.
4271
+ * Their immediate list type is still updated because the nested item was part of
4272
+ * the toolbar selection.
4273
+ *
4274
+ * @param {RTEBlock[]} selectedBlocks - Blocks selected by the toolbar action.
4275
+ * @param {ListType} listType - Target list type.
4276
+ * @returns {RTEBlock[]} Top-level selected blocks to emit into the rebuilt list.
4277
+ */
4278
+ function normalizeMixedListSelection(selectedBlocks, listType) {
4279
+ const selectedListItems = new Set(selectedBlocks.filter((block) => block.dtoName === 'RTEListItemBlock'));
4280
+ return selectedBlocks.filter((block) => {
4281
+ if (!(block.dtoName === 'RTEListItemBlock')) {
4282
+ return true;
4283
+ }
4284
+ let parentList = block.parent;
4285
+ while (parentList.parent && parentList.parent.dtoName === 'RTEListItemBlock') {
4286
+ const ownerItem = parentList.parent;
4287
+ if (selectedListItems.has(ownerItem)) {
4288
+ block.parent.type = listType;
4289
+ return false;
4290
+ }
4291
+ parentList = ownerItem.parent;
4292
+ }
4293
+ return true;
4294
+ });
4295
+ }
4296
+
4264
4297
  /**
4265
4298
  * Convert the selected blocks to list strategy.
4266
4299
  */
@@ -4272,12 +4305,16 @@ class BlockTransformToListStrategy extends ActionHandleStrategy {
4272
4305
  * @param {RTETextBlock} target - The first item of the selected block.
4273
4306
  */
4274
4307
  handleAction(action, target) {
4275
- const contentState = target.parent;
4308
+ const contentState = this.getRootContent(target);
4309
+ if (!contentState) {
4310
+ return;
4311
+ }
4312
+ const container = target.parent;
4276
4313
  const bulletList = contentState.createList(action.listType);
4277
- const selectedBlocks = action.selectedBlocks;
4314
+ const selectedBlocks = normalizeMixedListSelection(action.selectedBlocks, action.listType);
4278
4315
  const listItems = selectedBlocks.map((block) => contentState.toListItem(block));
4279
4316
  bulletList.apply(new AppendChildrenAction(listItems));
4280
- contentState.apply(new InsertChildrenAfterAction(action.selectedBlocks[0], bulletList));
4317
+ container.apply(new InsertChildrenAfterAction(action.selectedBlocks[0], bulletList));
4281
4318
  selectedBlocks.forEach((block) => {
4282
4319
  block.parent.apply(new RemoveChildrenAction(block));
4283
4320
  });
@@ -4674,78 +4711,1485 @@ class RTETextBlock extends RTEBlock {
4674
4711
  RTETextBlock.dtoName = 'RTETextBlock';
4675
4712
 
4676
4713
  /**
4677
- * The delete node content contains some common functions that used for image block delete the image node or text block delete text node.
4714
+ * Remove list item nest list block strategy.
4678
4715
  */
4679
- class BlockDeleteNodeContentStrategy extends ActionHandleStrategy {
4716
+ class ListItemRemoveNestListStrategy extends ActionHandleStrategy {
4680
4717
  /**
4681
- * Returns the previous node relative to the current node in a rich text editor structure.
4718
+ * Remove the nest list block from the list item, clear the property children when the children is empty.
4682
4719
  *
4683
- * @param {RTENode} currentNode - An object of type `RTENode`.
4684
- * @returns {Nullable<RTENode>} the previous block last node
4720
+ * @param {RemoveNestListAction} action - The action instance.
4721
+ * @param {RTEListItemBlock} target - The list item block.
4685
4722
  */
4686
- getPreviousNode(currentNode) {
4687
- const currentBlock = currentNode.parent;
4688
- const currentIndex = currentBlock.children.indexOf(currentNode);
4689
- if (currentIndex > 0) {
4690
- return currentBlock.children[currentIndex - 1];
4723
+ handleAction(action, target) {
4724
+ if (target.nestList) {
4725
+ if (target.nestList.length > 1) {
4726
+ target.nestList = target.nestList.filter((child) => child !== action.nestListBlockToBeRemoved);
4727
+ }
4728
+ else {
4729
+ target.nestList = undefined;
4730
+ }
4691
4731
  }
4692
- else if (currentBlock.parent) {
4693
- const previousBlock = this.getPreviousBlock(currentBlock);
4694
- if (previousBlock) {
4695
- return this.getBlockLastNode(previousBlock);
4732
+ }
4733
+ }
4734
+
4735
+ /**
4736
+ * Base strategy for list operations that reconstruct or merge list containers.
4737
+ * Keeps annotation cloning and equality rules consistent across those operations.
4738
+ */
4739
+ class ListAnnotationStrategy extends ActionHandleStrategy {
4740
+ /**
4741
+ * Copy list-container annotations without sharing mutable annotation instances.
4742
+ * Factory-provided defaults remain intact unless the source supplies the same key.
4743
+ *
4744
+ * @param {RTEListBlock} source - List whose annotations should be copied.
4745
+ * @param {RTEListBlock} target - Newly created list receiving the annotations.
4746
+ */
4747
+ copyListAnnotations(source, target) {
4748
+ source.annotationMap.forEach((annotation, key) => {
4749
+ target.annotationMap.set(key, annotation.clone());
4750
+ });
4751
+ }
4752
+ /**
4753
+ * Compare list annotations independently of map/object insertion order. Map keys
4754
+ * are compared separately because rendering annotations such as LIST intentionally
4755
+ * do not serialize to the DTO but still affect the rendered list.
4756
+ * Array order remains significant because it can affect rendered class order.
4757
+ *
4758
+ * @param {RTEListBlock} first - First list to compare.
4759
+ * @param {RTEListBlock} second - Second list to compare.
4760
+ * @returns {boolean} Whether both list containers have equivalent annotations.
4761
+ */
4762
+ haveSameListAnnotations(first, second) {
4763
+ var _a, _b;
4764
+ const firstKeys = Array.from(first.annotationMap.keys()).sort();
4765
+ const secondKeys = Array.from(second.annotationMap.keys()).sort();
4766
+ if (JSON.stringify(firstKeys) !== JSON.stringify(secondKeys)) {
4767
+ return false;
4768
+ }
4769
+ return (JSON.stringify(this.normalizeAnnotationValue((_a = first.toJSON().annotations) !== null && _a !== void 0 ? _a : {})) ===
4770
+ JSON.stringify(this.normalizeAnnotationValue((_b = second.toJSON().annotations) !== null && _b !== void 0 ? _b : {})));
4771
+ }
4772
+ /**
4773
+ * Recursively sort object keys for stable annotation comparison.
4774
+ *
4775
+ * @param {unknown} value - Annotation value to normalize.
4776
+ * @returns {unknown} Normalized annotation value.
4777
+ */
4778
+ normalizeAnnotationValue(value) {
4779
+ if (Array.isArray(value)) {
4780
+ return value.map((item) => this.normalizeAnnotationValue(item));
4781
+ }
4782
+ if (value && typeof value === 'object') {
4783
+ const record = value;
4784
+ return Object.keys(record)
4785
+ .sort()
4786
+ .reduce((normalized, key) => {
4787
+ normalized[key] = this.normalizeAnnotationValue(record[key]);
4788
+ return normalized;
4789
+ }, {});
4790
+ }
4791
+ return value;
4792
+ }
4793
+ }
4794
+
4795
+ /**
4796
+ * Replace list item nest list strategy.
4797
+ *
4798
+ * This is the single write-through point for `nestList` mutations. It automatically
4799
+ * normalizes the incoming array by merging adjacent lists only when their types
4800
+ * and container annotations match. Styled list boundaries remain independent.
4801
+ */
4802
+ class ListItemReplaceNestListStrategy extends ListAnnotationStrategy {
4803
+ /**
4804
+ * @inheritDoc
4805
+ */
4806
+ handleAction(action, target) {
4807
+ const normalized = this.mergeAdjacentSameType(action.newList);
4808
+ normalized.forEach((listBlock) => {
4809
+ listBlock.parent = target;
4810
+ });
4811
+ target.nestList = normalized;
4812
+ }
4813
+ /**
4814
+ * Merge adjacent entries that share the same list type and annotations.
4815
+ * This is an idempotent O(n) pass — calling it on an already-normalized array is a no-op.
4816
+ *
4817
+ * @param {RTEListBlock[]} lists - The nest list array to normalize.
4818
+ * @returns {RTEListBlock[]} A new array with adjacent same-type entries merged.
4819
+ */
4820
+ mergeAdjacentSameType(lists) {
4821
+ if (lists.length <= 1) {
4822
+ return lists;
4823
+ }
4824
+ const merged = [lists[0]];
4825
+ for (let i = 1; i < lists.length; i++) {
4826
+ const prev = merged[merged.length - 1];
4827
+ const current = lists[i];
4828
+ if (prev.type === current.type && this.haveSameListAnnotations(prev, current)) {
4829
+ current.children.forEach((item) => {
4830
+ item.parent = prev;
4831
+ });
4832
+ prev.children = prev.children.concat(current.children);
4833
+ }
4834
+ else {
4835
+ merged.push(current);
4696
4836
  }
4697
4837
  }
4838
+ return merged;
4698
4839
  }
4840
+ }
4841
+
4842
+ /**
4843
+ * Insert image node to list item block strategy.
4844
+ */
4845
+ class ListItemInsertImageStrategy extends ActionHandleStrategy {
4699
4846
  /**
4700
- * Returns the next node relative to the current node in a rich text editor structure.
4847
+ * The image node can not insert into list item block, so insert image after parent list block.
4701
4848
  *
4702
- * @param {RTENode} currentNode - An object of type `RTENode`.
4703
- * @returns {Nullable<RTENode>} the next block first node
4849
+ * @param {InsertImageToBlockAction} action - The action instance.
4850
+ * @param {RTEListItemBlock} target - The list item block.
4704
4851
  */
4705
- getNextNode(currentNode) {
4706
- const currentBlock = currentNode.parent;
4707
- const currentIndex = currentBlock.children.indexOf(currentNode);
4708
- if (currentBlock.children[currentIndex + 1]) {
4709
- return currentBlock.children[currentIndex + 1];
4852
+ handleAction(action, target) {
4853
+ target.parent.apply(action);
4854
+ }
4855
+ }
4856
+
4857
+ /**
4858
+ * List item block.
4859
+ *
4860
+ * Bidirectional nesting contract:
4861
+ * - nestList stores nested list blocks owned by this list item.
4862
+ * - Every nested list block must have listBlock.parent === this list item.
4863
+ */
4864
+ class RTEListItemBlock extends RTETextBlock {
4865
+ constructor(id, nestList, options) {
4866
+ super(id, 'list-item', options);
4867
+ this.dtoName = RTEListItemBlock.dtoName;
4868
+ /**
4869
+ * TODO: Refactor the list item properties children and nestList, merge two properties together.
4870
+ *
4871
+ * 1. Update the type of `children` to include `RTEListBlock` as a possible type.
4872
+ * 2. The list block children should text block array and nest list block array, The text block should wrap a `li` tag when rendering.
4873
+ */
4874
+ this.nestList = [];
4875
+ this.nestList = nestList;
4876
+ }
4877
+ /**
4878
+ * Converts a VegaRTEListItemBlock object to an RTEListItemBlock
4879
+ *
4880
+ * @param {VegaRTEListBlock} block - Converts a `VegaRTEListItemBlock` object into an `RTEListItemBlock`.
4881
+ * @param {VegaRTETransformOptions} options - Optional transformation options.
4882
+ * @returns {RTEListItemBlock} Return an instance of `RTEListItemBlock`
4883
+ */
4884
+ static from(block, options = { autoMatchFormat: true }) {
4885
+ const listItemBlock = new RTEListItemBlock(block.id, undefined, options);
4886
+ listItemBlock.children = block.nodes.map((richText) => RTETextNode.from(richText, listItemBlock, options));
4887
+ if (block.children) {
4888
+ listItemBlock.nestList = block.children.map((child) => {
4889
+ const listBlock = RTEListBlock.from(child, options);
4890
+ listBlock.parent = listItemBlock;
4891
+ return listBlock;
4892
+ });
4710
4893
  }
4711
- else if (currentBlock.parent) {
4712
- const nextBlock = this.getNextBlock(currentBlock);
4713
- if (nextBlock) {
4714
- return this.getBlockFirstNode(nextBlock);
4894
+ const { annotations } = block;
4895
+ if (annotations) {
4896
+ Object.entries(annotations).forEach(([type, value]) => {
4897
+ const item = this.createAnnotationEntity(type, value);
4898
+ if (typeGuard.isNonNullable(item)) {
4899
+ listItemBlock.annotationMap.set(...item);
4900
+ }
4901
+ });
4902
+ }
4903
+ return listItemBlock;
4904
+ }
4905
+ /**
4906
+ * @inheritDoc
4907
+ */
4908
+ toJSON() {
4909
+ var _a;
4910
+ return Object.assign(Object.assign({}, super.toJSON()), { type: 'list-item', children: (_a = this.nestList) === null || _a === void 0 ? void 0 : _a.map((block) => block.toJSON()) });
4911
+ }
4912
+ /**
4913
+ * @inheritDoc
4914
+ */
4915
+ toHtml(options) {
4916
+ var _a;
4917
+ const attrStr = super.generateAttributeString(options);
4918
+ const nestListHtml = ((_a = this.nestList) === null || _a === void 0 ? void 0 : _a.length)
4919
+ ? this.nestList.map((list) => list.toHtml(options)).join('')
4920
+ : '';
4921
+ return [`<li${attrStr}>`, this.getChildrenHtml(options), nestListHtml, `</li>`].join('');
4922
+ }
4923
+ /**
4924
+ * @inheritDoc
4925
+ */
4926
+ cloneWithNodes(nodes) {
4927
+ const block = new RTEListItemBlock(misc.generateUUID());
4928
+ block.children = [];
4929
+ block.apply(new AppendChildrenAction(nodes));
4930
+ return block;
4931
+ }
4932
+ /**
4933
+ * @inheritDoc
4934
+ */
4935
+ getLastNode() {
4936
+ if (this.nestList && this.nestList.length > 0) {
4937
+ const childListBlock = this.nestList[this.nestList.length - 1];
4938
+ return childListBlock.getLastNode();
4939
+ }
4940
+ return super.getLastNode();
4941
+ }
4942
+ /**
4943
+ * Create a new list item block.
4944
+ *
4945
+ * @returns {RTEListItemBlock} - A list item block.
4946
+ */
4947
+ createNewListItem() {
4948
+ return new RTEListItemBlock(misc.generateUUID());
4949
+ }
4950
+ /**
4951
+ * @inheritDoc
4952
+ */
4953
+ clone(parent) {
4954
+ var _a;
4955
+ const block = new RTEListItemBlock(this.id);
4956
+ block.children = this.children.map((node) => node.clone(block));
4957
+ block.annotationMap = super.cloneAnnotations();
4958
+ block.nestList = (_a = this.nestList) === null || _a === void 0 ? void 0 : _a.map((child) => child.clone(block));
4959
+ block.parent = parent;
4960
+ return block;
4961
+ }
4962
+ }
4963
+ (() => {
4964
+ ActionHandleStrategyRegistry.register(TextStyleAnnotationAction.name, RTEListItemBlock.name, new BlockUpdateTextStyleStrategy());
4965
+ ActionHandleStrategyRegistry.register(HorizontalAlignmentAnnotationAction.name, RTEListItemBlock.name, new BlockUpdateHorizontalAlignmentStrategy());
4966
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.LINE_BREAK_SINGLE_BLOCK, RTEListItemBlock.name, new BlockInsertLineBreakStrategy());
4967
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.LINE_BREAK_MULTIPLE_BLOCKS, RTEListItemBlock.name, new BlockInsertLineBreakWithBlocksStrategy());
4968
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.DELETE_NEST_LIST, RTEListItemBlock.name, new ListItemRemoveNestListStrategy());
4969
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.SPLIT_BLOCK_WITH_NODE, RTEListItemBlock.name, new BlockSplitWithTextNodeStrategy());
4970
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.REPLACE_CHILD_NODES, RTEListItemBlock.name, new BlockReplaceNodesStrategy());
4971
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.REPLACE_NEST_LIST, RTEListItemBlock.name, new ListItemReplaceNestListStrategy());
4972
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.MERGE_TWO_BLOCKS_NODES, RTEListItemBlock.name, new BlockMergeNodesStrategy());
4973
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.INSERT_IMAGE_TO_BLOCK, RTEListItemBlock.name, new ListItemInsertImageStrategy());
4974
+ })();
4975
+ RTEListItemBlock.dtoName = 'RTEListItemBlock';
4976
+
4977
+ /**
4978
+ * Replace the nest list with new list array
4979
+ *
4980
+ * @example listItemBlock.apply(new ReplaceNestListAction(newListBlockArray))
4981
+ */
4982
+ class ReplaceNestListAction extends ModifyContentAction {
4983
+ constructor(newList) {
4984
+ super();
4985
+ this.type = exports.ModifyContentActionType.REPLACE_NEST_LIST;
4986
+ this.newList = newList;
4987
+ }
4988
+ }
4989
+
4990
+ /**
4991
+ * Convert the selected blocks to list strategy.
4992
+ */
4993
+ class ListTransformToListStrategy extends ListAnnotationStrategy {
4994
+ /**
4995
+ * @inheritDoc
4996
+ */
4997
+ handleAction(action, target) {
4998
+ var _a;
4999
+ const selectedBlocks = action.selectedBlocks;
5000
+ const isSameList = selectedBlocks.every((block) => block.parent === target);
5001
+ const rootContent = this.getRootContent(target);
5002
+ if (!rootContent) {
5003
+ return;
5004
+ }
5005
+ // Nested list case: target.parent is RTEListItemBlock, not VegaRTEContent.
5006
+ // Replace the entry in the parent item's nestList using the existing ReplaceNestListAction.
5007
+ if (target.parent instanceof RTEListItemBlock) {
5008
+ if (isSameList) {
5009
+ const newList = this.createListFromSource(rootContent, target, action.listType);
5010
+ newList.apply(new AppendChildrenAction(target.children));
5011
+ const parentListItem = target.parent;
5012
+ const newNestList = ((_a = parentListItem.nestList) !== null && _a !== void 0 ? _a : []).map((list) => (list === target ? newList : list));
5013
+ // Adjacent same-type merge is handled automatically by ListItemReplaceNestListStrategy.
5014
+ parentListItem.apply(new ReplaceNestListAction(newNestList));
5015
+ selectedBlocks.forEach((block) => block.children.map((node) => node.apply(new SyncUpSelectionAction())));
5016
+ }
5017
+ else {
5018
+ this.handleCrossListTransform(action, target);
5019
+ }
5020
+ return;
5021
+ }
5022
+ // Root list case: target.parent is VegaRTEContent.
5023
+ // When all selected blocks are list items from different lists, convert each
5024
+ // affected list's type in place (preserving nesting), then normalize adjacent
5025
+ // same-type root lists into one.
5026
+ if (!isSameList && selectedBlocks.every((block) => block instanceof RTEListItemBlock)) {
5027
+ const affectedLists = new Set(selectedBlocks.map((block) => block.parent));
5028
+ // Track which root lists result from conversion (new lists replace old ones).
5029
+ const convertedRootLists = new Set();
5030
+ affectedLists.forEach((list) => {
5031
+ if (list.type !== action.listType) {
5032
+ this.convertListTypeInPlace(list, action.listType);
5033
+ }
5034
+ });
5035
+ // Collect current top-level lists that contain any selected item, grouped
5036
+ // by their root or HTML-block container.
5037
+ const affectedContainers = new Set();
5038
+ selectedBlocks.forEach((block) => {
5039
+ const parentList = block.parent;
5040
+ if (!(parentList.parent instanceof RTEListItemBlock)) {
5041
+ convertedRootLists.add(parentList);
5042
+ affectedContainers.add(parentList.parent);
5043
+ }
5044
+ });
5045
+ // Only merge adjacent root lists when BOTH are affected by this transform.
5046
+ affectedContainers.forEach((container) => {
5047
+ for (let i = 0; i < container.children.length - 1;) {
5048
+ const current = container.children[i];
5049
+ const next = container.children[i + 1];
5050
+ if (current instanceof RTEListBlock &&
5051
+ next instanceof RTEListBlock &&
5052
+ current.type === next.type &&
5053
+ this.haveSameListAnnotations(current, next) &&
5054
+ convertedRootLists.has(current) &&
5055
+ convertedRootLists.has(next)) {
5056
+ current.apply(new AppendChildrenAction([...next.children]));
5057
+ container.apply(new RemoveChildrenAction(next));
5058
+ convertedRootLists.delete(next);
5059
+ }
5060
+ else {
5061
+ i++;
5062
+ }
5063
+ }
5064
+ });
5065
+ selectedBlocks.forEach((block) => block.children.map((node) => node.apply(new SyncUpSelectionAction())));
5066
+ return;
5067
+ }
5068
+ const bulletList = this.createListFromSource(rootContent, target, action.listType);
5069
+ const targetContainer = target.parent;
5070
+ if (isSameList) {
5071
+ // Select one or more list items belonging to the same list, and all items in this list should be updated
5072
+ bulletList.apply(new AppendChildrenAction(target.children));
5073
+ targetContainer.apply(new InsertChildrenAfterAction(target, bulletList));
5074
+ targetContainer.apply(new RemoveChildrenAction(target));
5075
+ selectedBlocks.forEach((block) => block.children.map((node) => node.apply(new SyncUpSelectionAction())));
5076
+ }
5077
+ else {
5078
+ const mixedSelection = normalizeMixedListSelection(action.selectedBlocks, action.listType);
5079
+ const listItems = mixedSelection.map((block) => rootContent.toListItem(block));
5080
+ bulletList.apply(new AppendChildrenAction(listItems));
5081
+ targetContainer.apply(new InsertChildrenAfterAction(target, bulletList));
5082
+ mixedSelection.forEach((block) => {
5083
+ block.parent.apply(new RemoveChildrenAction(block));
5084
+ });
5085
+ if (target.children.length === 0) {
5086
+ targetContainer.apply(new RemoveChildrenAction(target));
4715
5087
  }
4716
5088
  }
4717
5089
  }
4718
5090
  /**
4719
- * Determines if a given node is the first node within the current state.
5091
+ * Convert a single list's type in place, preserving its items and their nested
5092
+ * structure. Root lists are swapped in the content children; nested lists are
5093
+ * swapped inside their parent item's nestList.
4720
5094
  *
4721
- * @param {RTENode} currentNode - An object representing a node in a rich text editor (RTE).
4722
- * @returns {boolean} True or false;
5095
+ * @param {RTEListBlock} list - The list whose type should be converted.
5096
+ * @param {RTEListBlock['type']} listType - The target list type.
4723
5097
  */
4724
- isContentFirstNode(currentNode) {
4725
- const currentBlock = currentNode.parent;
4726
- const currentIndex = currentBlock.children.indexOf(currentNode);
4727
- const parent = currentBlock.parent;
4728
- if (currentBlock.isListItemBlock()) {
4729
- const listParent = parent.parent;
4730
- return (currentIndex === 0 &&
4731
- Array.isArray(parent.children) &&
4732
- parent.children[0] === currentBlock &&
4733
- listParent['type'] !== 'list-item' &&
4734
- Array.isArray(listParent.children) &&
4735
- listParent.children[0] === parent);
5098
+ convertListTypeInPlace(list, listType) {
5099
+ var _a;
5100
+ const rootContent = this.getRootContent(list);
5101
+ if (!rootContent) {
5102
+ return;
5103
+ }
5104
+ const parent = list.parent;
5105
+ const newList = this.createListFromSource(rootContent, list, listType);
5106
+ newList.apply(new AppendChildrenAction([...list.children]));
5107
+ if (parent instanceof RTEListItemBlock) {
5108
+ // Adjacent same-type merge is handled automatically by ListItemReplaceNestListStrategy.
5109
+ const newNestList = ((_a = parent.nestList) !== null && _a !== void 0 ? _a : []).map((entry) => entry === list ? newList : entry);
5110
+ parent.apply(new ReplaceNestListAction(newNestList));
4736
5111
  }
4737
5112
  else {
4738
- return (currentIndex === 0 && Array.isArray(parent.children) && parent.children[0] === currentBlock);
5113
+ parent.apply(new InsertChildrenAfterAction(list, newList));
5114
+ parent.apply(new RemoveChildrenAction(list));
4739
5115
  }
4740
5116
  }
4741
5117
  /**
4742
- * TODO: The getPreviousBlock add nest list support
4743
- * This function retrieves the previous block in a rich text editor, considering different scenarios such as being in a bullet list.
5118
+ * Handle the case where selected blocks span multiple nestLists under the same parent item.
5119
+ * Transform each affected list and then merge adjacent same-type lists.
4744
5120
  *
4745
- * @param {RTEBlock} currentBlock - Used to retrieve the previous block relative to the given `currentBlock` within a rich text editor context.
4746
- * @returns {Nullable<RTEBlock>} The previous block if existing
5121
+ * @param {TransformListAction} action - The transform action with selection and target list type.
5122
+ * @param {RTEListBlock} target - The nested list where transformation starts.
4747
5123
  */
4748
- getPreviousBlock(currentBlock) {
5124
+ handleCrossListTransform(action, target) {
5125
+ if (!(target.parent instanceof RTEListItemBlock)) {
5126
+ return;
5127
+ }
5128
+ const rootContent = this.getRootContent(target);
5129
+ if (!rootContent) {
5130
+ return;
5131
+ }
5132
+ const parentListItem = target.parent;
5133
+ const parentNestLists = parentListItem.nestList;
5134
+ const affectedLists = new Set(action.selectedBlocks
5135
+ .filter((block) => block instanceof RTEListItemBlock)
5136
+ .map((block) => block.parent)
5137
+ .filter((list) => parentNestLists.includes(list)));
5138
+ if (!affectedLists.size) {
5139
+ return;
5140
+ }
5141
+ const newNestList = parentNestLists.map((list) => {
5142
+ if (!affectedLists.has(list)) {
5143
+ return list;
5144
+ }
5145
+ const newList = this.createListFromSource(rootContent, list, action.listType);
5146
+ newList.apply(new AppendChildrenAction(list.children));
5147
+ return newList;
5148
+ });
5149
+ // Adjacent same-type merge is handled automatically by ListItemReplaceNestListStrategy.
5150
+ parentListItem.apply(new ReplaceNestListAction(newNestList));
5151
+ action.selectedBlocks.forEach((block) => block.children.map((node) => node.apply(new SyncUpSelectionAction())));
5152
+ }
5153
+ /**
5154
+ * Create a replacement list through the owning content factory while retaining
5155
+ * the source list's container annotations.
5156
+ *
5157
+ * @param {VegaRTEContent} rootContent - Editor content owning the factory.
5158
+ * @param {RTEListBlock} source - List whose annotations should be retained.
5159
+ * @param {RTEListBlock['type']} listType - Replacement list type.
5160
+ * @returns {RTEListBlock} New annotated list shell.
5161
+ */
5162
+ createListFromSource(rootContent, source, listType) {
5163
+ const list = rootContent.createList(listType);
5164
+ this.copyListAnnotations(source, list);
5165
+ return list;
5166
+ }
5167
+ }
5168
+
5169
+ /**
5170
+ * Action to toggle bullet annotation
5171
+ */
5172
+ class TransformParagraphAction extends ModifyContentAction {
5173
+ constructor(selectedBlocks) {
5174
+ super();
5175
+ this.type = exports.ModifyContentActionType.TRANSFORM_PARAGRAPH_BLOCK;
5176
+ this.isFlushable = true;
5177
+ this.selectedBlocks = selectedBlocks;
5178
+ }
5179
+ }
5180
+
5181
+ /**
5182
+ * HTML Block
5183
+ */
5184
+ class RTEHtmlBlock extends RTEBlock {
5185
+ constructor(id, htmlTag) {
5186
+ super(id);
5187
+ this.dtoName = RTEHtmlBlock.dtoName;
5188
+ this.type = 'html-block';
5189
+ this.children = [];
5190
+ this.htmlTag = htmlTag;
5191
+ }
5192
+ /**
5193
+ * Converts a VegaRTEHtmlBlock to an RTEHtmlBlock.
5194
+ *
5195
+ * @param {VegaRTEHtmlBlock} block - The VegaRTEHtmlBlock to convert.
5196
+ * @param {VegaRTETransformOptions} [options] - Optional transformation options.
5197
+ * @returns {RTEHtmlBlock} The converted RTEHtmlBlock.
5198
+ */
5199
+ static from(block, options) {
5200
+ const htmlBlock = new RTEHtmlBlock(block.id, block.htmlTag);
5201
+ const { annotations } = block;
5202
+ if (annotations) {
5203
+ super.convertAnnotationsToMap(htmlBlock.annotationMap, annotations);
5204
+ }
5205
+ htmlBlock.children = this.generateBlockChildren(block.children, options, htmlBlock);
5206
+ return htmlBlock;
5207
+ }
5208
+ /**
5209
+ * @inheritDoc
5210
+ */
5211
+ clone(parent) {
5212
+ const clonedBlock = new RTEHtmlBlock(this.id, this.htmlTag);
5213
+ clonedBlock.children = this.children.map((child) => child.clone(clonedBlock));
5214
+ clonedBlock.annotationMap = super.cloneAnnotations();
5215
+ clonedBlock.parent = parent;
5216
+ return clonedBlock;
5217
+ }
5218
+ /**
5219
+ * @inheritDoc
5220
+ */
5221
+ getLastNode() {
5222
+ return this.children[this.children.length - 1].getLastNode();
5223
+ }
5224
+ /**
5225
+ * @inheritDoc
5226
+ */
5227
+ isNotEmpty() {
5228
+ // Any RTEHtmlBlock — whether void (hr, br), childless (canvas, iframe),
5229
+ // or with children — represents real user content. Only the default empty
5230
+ // text paragraph should make the editor report as empty.
5231
+ return true;
5232
+ }
5233
+ /**
5234
+ * @inheritDoc
5235
+ */
5236
+ toHtml(options) {
5237
+ const BlockTag = this.htmlTag;
5238
+ const attrStr = super.generateAttributeString(options);
5239
+ // Handle void/self-closing tags (hr, input, col, etc.)
5240
+ // Uses HTML5 syntax without self-closing slash for consistency with img and br tags
5241
+ if (HTML_VOID_TAGS.has(this.htmlTag)) {
5242
+ return `<${BlockTag}${attrStr}>`;
5243
+ }
5244
+ // Handle normal tags with children
5245
+ return [
5246
+ `<${BlockTag}${attrStr}>`,
5247
+ this.children.map((block) => block.toHtml(options)).join(''),
5248
+ `</${BlockTag}>`,
5249
+ ].join('');
5250
+ }
5251
+ /**
5252
+ * @inheritDoc
5253
+ */
5254
+ toJSON() {
5255
+ return Object.assign(Object.assign({}, super.toJSON()), { id: this.id, type: this.type, htmlTag: this.htmlTag, children: this.children.map((child) => child.toJSON()) });
5256
+ }
5257
+ }
5258
+ RTEHtmlBlock.dtoName = 'RTEHtmlBlock';
5259
+
5260
+ /**
5261
+ * Convert the selected list block to paragraph strategy.
5262
+ */
5263
+ class ListTransformToParagraphStrategy extends ListAnnotationStrategy {
5264
+ /**
5265
+ * @inheritDoc
5266
+ */
5267
+ handleAction(action, target) {
5268
+ const selectedSegments = this.getSelectedSegments(action.selectedBlocks);
5269
+ if (selectedSegments.length === 0 || !this.hasConsistentTargetAndRoot(selectedSegments, target)) {
5270
+ return;
5271
+ }
5272
+ this.syncSelection(selectedSegments);
5273
+ [...selectedSegments]
5274
+ .reverse()
5275
+ .forEach((segment) => this.transformSegment(segment));
5276
+ }
5277
+ /**
5278
+ * Ensure the action is applied to the first selected item's parent list and
5279
+ * every selected item belongs to the same editor content.
5280
+ *
5281
+ * @param {RTEListItemBlock[][]} selectedSegments - Normalized selection segments.
5282
+ * @param {RTEListBlock} target - List receiving the transform action.
5283
+ * @returns {boolean} Whether the target and root content are consistent.
5284
+ */
5285
+ hasConsistentTargetAndRoot(selectedSegments, target) {
5286
+ if (selectedSegments[0][0].parent !== target) {
5287
+ return false;
5288
+ }
5289
+ const targetRoot = this.getRootContent(target);
5290
+ return Boolean(targetRoot &&
5291
+ selectedSegments.every((segment) => segment.every((item) => this.getRootContent(item) === targetRoot)));
5292
+ }
5293
+ /**
5294
+ * Capture selected text nodes in document order before reverse-order tree
5295
+ * mutations move them into paragraphs.
5296
+ *
5297
+ * @param {RTEListItemBlock[][]} selectedSegments - Normalized selection segments.
5298
+ */
5299
+ syncSelection(selectedSegments) {
5300
+ selectedSegments.forEach((segment) => {
5301
+ segment.forEach((block) => {
5302
+ block.children.forEach((node) => node.apply(new SyncUpSelectionAction()));
5303
+ });
5304
+ });
5305
+ }
5306
+ /**
5307
+ * Transform one normalized segment without recursively dispatching another
5308
+ * flushable action.
5309
+ *
5310
+ * @param {RTEListItemBlock[]} segment - Contiguous items sharing one parent list.
5311
+ */
5312
+ transformSegment(segment) {
5313
+ const segmentTarget = segment[0].parent;
5314
+ const normalizedAction = new TransformParagraphAction(segment);
5315
+ if (segmentTarget.parent instanceof RTEListItemBlock) {
5316
+ this.handleNestedListCase(normalizedAction, segmentTarget);
5317
+ return;
5318
+ }
5319
+ this.handleRootListCase(normalizedAction, segmentTarget);
5320
+ }
5321
+ /**
5322
+ * Handle the case where the target list is at root level (parent is VegaRTEContent).
5323
+ *
5324
+ * @param {TransformParagraphAction} action - The paragraph transform action.
5325
+ * @param {RTEListBlock} target - The root list being transformed.
5326
+ */
5327
+ handleRootListCase(action, target) {
5328
+ // handleAction validates that the target belongs to an editor content root.
5329
+ const rootContent = this.getRootContent(target);
5330
+ let isSelectedFirstBlock = false;
5331
+ let isSelectedLastBlock = false;
5332
+ const selectedBlocks = action.selectedBlocks;
5333
+ // Build an operation-local insertion sequence. Paragraphs are merge
5334
+ // boundaries; only consecutive same-type promoted lists are merged.
5335
+ const insertionBlocks = [];
5336
+ selectedBlocks.forEach((block) => {
5337
+ var _a;
5338
+ if (block === target.children[0])
5339
+ isSelectedFirstBlock = true;
5340
+ if (block === target.children[target.children.length - 1])
5341
+ isSelectedLastBlock = true;
5342
+ insertionBlocks.push(this.toParagraph(block));
5343
+ for (const nestList of (_a = block.nestList) !== null && _a !== void 0 ? _a : []) {
5344
+ this.appendListBlock(insertionBlocks, nestList);
5345
+ }
5346
+ });
5347
+ if (isSelectedFirstBlock) {
5348
+ target.parent.apply(new InsertChildrenBeforeAction(target, ...insertionBlocks));
5349
+ }
5350
+ else if (isSelectedLastBlock) {
5351
+ target.parent.apply(new InsertChildrenAfterAction(target, ...insertionBlocks));
5352
+ }
5353
+ else {
5354
+ const startIndex = target.children.indexOf(selectedBlocks[0]);
5355
+ const lastIndex = target.children.indexOf(selectedBlocks[selectedBlocks.length - 1]);
5356
+ const firstBulletList = this.createListFromSource(rootContent, target);
5357
+ firstBulletList.apply(new AppendChildrenAction(target.children.slice(0, startIndex)));
5358
+ const lastBulletList = this.createListFromSource(rootContent, target);
5359
+ lastBulletList.apply(new AppendChildrenAction(target.children.slice(lastIndex + 1)));
5360
+ // Merge last insertionBlock with lastBulletList if same type
5361
+ const lastInsertion = insertionBlocks[insertionBlocks.length - 1];
5362
+ if (lastInsertion instanceof RTEListBlock &&
5363
+ lastBulletList.children.length > 0 &&
5364
+ lastInsertion.type === lastBulletList.type &&
5365
+ this.haveSameListAnnotations(lastInsertion, lastBulletList)) {
5366
+ lastInsertion.apply(new AppendChildrenAction(lastBulletList.children));
5367
+ target.parent.apply(new InsertChildrenBeforeAction(target, firstBulletList, ...insertionBlocks));
5368
+ }
5369
+ else {
5370
+ target.parent.apply(new InsertChildrenBeforeAction(target, firstBulletList, ...insertionBlocks, lastBulletList));
5371
+ }
5372
+ target.parent.apply(new RemoveChildrenAction(target));
5373
+ }
5374
+ selectedBlocks.map((block) => {
5375
+ // Clear nestList before removal to prevent ListRemoveListItemStrategy
5376
+ // from promoting the same nested lists a second time.
5377
+ block.nestList = [];
5378
+ target.apply(new RemoveChildrenAction(block));
5379
+ });
5380
+ if (target.children.length === 0) {
5381
+ target.parent.apply(new RemoveChildrenAction(target));
5382
+ }
5383
+ else if (isSelectedFirstBlock) {
5384
+ // When removing the first item(s), a promoted same-type nestList (last
5385
+ // insertionBlock) ends up immediately before the remaining target. Merge
5386
+ // them so the user doesn't see two adjacent same-type lists.
5387
+ const lastInserted = insertionBlocks[insertionBlocks.length - 1];
5388
+ if (lastInserted instanceof RTEListBlock &&
5389
+ lastInserted.type === target.type &&
5390
+ this.haveSameListAnnotations(lastInserted, target)) {
5391
+ lastInserted.apply(new AppendChildrenAction([...target.children]));
5392
+ target.parent.apply(new RemoveChildrenAction(target));
5393
+ }
5394
+ }
5395
+ }
5396
+ /**
5397
+ * Handle the case where the target list is nested (parent is RTEListItemBlock).
5398
+ *
5399
+ * Algorithm:
5400
+ * 1. Build the ancestor path from root list down to the target nested list.
5401
+ * 2. At each level on the path, collect "trailing" items (items after the ancestor).
5402
+ * 3. Trim each list along the path to keep only the "before" portion.
5403
+ * 4. Collect trailing items from all levels + selected item's own nestList children.
5404
+ * 5. Group trailing items into lists by consecutive type.
5405
+ * 6. Insert into content: [before-root-list, paragraphs, ...after-lists].
5406
+ *
5407
+ * @param {TransformParagraphAction} action - The paragraph transform action.
5408
+ * @param {RTEListBlock} target - The nested list being transformed.
5409
+ */
5410
+ handleNestedListCase(action, target) {
5411
+ const selectedBlocks = action.selectedBlocks;
5412
+ const rootContent = this.getRootContent(target);
5413
+ const selectedItem = selectedBlocks[0];
5414
+ const selectedIndex = target.children.indexOf(selectedItem);
5415
+ // Emit each selected item as paragraph + its own nested lists so that
5416
+ // selecting multiple levels never moves a child list past another paragraph.
5417
+ const insertions = [];
5418
+ selectedBlocks.forEach((block) => {
5419
+ var _a;
5420
+ insertions.push(this.toParagraph(block));
5421
+ for (const nestList of (_a = block.nestList) !== null && _a !== void 0 ? _a : []) {
5422
+ this.appendListBlock(insertions, nestList);
5423
+ }
5424
+ });
5425
+ const lastSelectedIndex = target.children.indexOf(selectedBlocks[selectedBlocks.length - 1]);
5426
+ // Collect trailing items from the nested list (items AFTER the last selected)
5427
+ const nestedTrailingItems = target.children.slice(lastSelectedIndex + 1);
5428
+ const ancestorPath = [];
5429
+ let currentList = target;
5430
+ while (currentList.parent instanceof RTEListItemBlock) {
5431
+ const parentItem = currentList.parent;
5432
+ const grandParentList = parentItem.parent;
5433
+ const ancestorIndex = grandParentList.children.indexOf(parentItem);
5434
+ // Collect nestLists of parentItem that are AFTER currentList
5435
+ const parentNestLists = parentItem.nestList;
5436
+ const nestListIndex = parentNestLists.indexOf(currentList);
5437
+ const trailingNestLists = parentNestLists.slice(nestListIndex + 1);
5438
+ ancestorPath.push({ list: grandParentList, ancestorIndex, trailingNestLists });
5439
+ currentList = grandParentList;
5440
+ }
5441
+ // currentList is now the root-level list
5442
+ const rootList = currentList;
5443
+ const rootContainer = rootList.parent;
5444
+ const trailingGroups = [];
5445
+ // 1. Trailing items from the target nested list (same type as target)
5446
+ if (nestedTrailingItems.length > 0) {
5447
+ trailingGroups.push({ items: nestedTrailingItems, sourceList: target });
5448
+ }
5449
+ // 2. Trailing nestLists from ancestors (innermost to outermost)
5450
+ // 3. Trailing items from each ancestor level's list
5451
+ for (const level of ancestorPath) {
5452
+ // Trailing nestLists from the ancestor item
5453
+ for (const trailingNest of level.trailingNestLists) {
5454
+ if (trailingNest.children.length > 0) {
5455
+ trailingGroups.push({ items: [...trailingNest.children], sourceList: trailingNest });
5456
+ }
5457
+ }
5458
+ // Trailing items from ancestor's list (items after the ancestor item)
5459
+ const trailingFromLevel = level.list.children.slice(level.ancestorIndex + 1);
5460
+ if (trailingFromLevel.length > 0) {
5461
+ trailingGroups.push({ items: trailingFromLevel, sourceList: level.list });
5462
+ }
5463
+ }
5464
+ // Merge only groups whose list type and container annotations match. Different
5465
+ // class/style/attribute boundaries must survive the structural reconstruction.
5466
+ const mergedGroups = [];
5467
+ for (const group of trailingGroups) {
5468
+ const prev = mergedGroups[mergedGroups.length - 1];
5469
+ if (prev &&
5470
+ prev.sourceList.type === group.sourceList.type &&
5471
+ this.haveSameListAnnotations(prev.sourceList, group.sourceList)) {
5472
+ prev.items.push(...group.items);
5473
+ }
5474
+ else {
5475
+ mergedGroups.push({ items: [...group.items], sourceList: group.sourceList });
5476
+ }
5477
+ }
5478
+ // Build the "after" lists
5479
+ const afterLists = mergedGroups.map((group) => {
5480
+ const newList = this.createListFromSource(rootContent, group.sourceList);
5481
+ newList.apply(new AppendChildrenAction(group.items));
5482
+ return newList;
5483
+ });
5484
+ afterLists.forEach((list) => this.appendListBlock(insertions, list));
5485
+ // --- Now trim the "before" portion ---
5486
+ // Trim target nested list: keep only items before selected
5487
+ target.children = target.children.slice(0, selectedIndex);
5488
+ // Clean up the target nested list's parent item's nestList
5489
+ const targetParentItem = target.parent;
5490
+ const targetParentNestLists = targetParentItem.nestList;
5491
+ const targetNestIndex = targetParentNestLists.indexOf(target);
5492
+ // Keep only nestLists up to and including the target (remove trailing ones we already collected)
5493
+ let trimmedNestList = targetParentNestLists.slice(0, targetNestIndex + 1);
5494
+ // If target is now empty, remove it too
5495
+ if (target.children.length === 0) {
5496
+ trimmedNestList = trimmedNestList.filter((l) => l !== target);
5497
+ }
5498
+ targetParentItem.apply(new ReplaceNestListAction(trimmedNestList));
5499
+ // Trim ancestor levels: remove trailing items and trailing nestLists
5500
+ for (const level of ancestorPath) {
5501
+ // Remove trailing items from the ancestor's list
5502
+ level.list.children = level.list.children.slice(0, level.ancestorIndex + 1);
5503
+ // Remove trailing nestLists from the ancestor item
5504
+ if (level.trailingNestLists.length > 0) {
5505
+ const ancestorItem = level.list.children[level.ancestorIndex];
5506
+ const ancestorNestLists = ancestorItem.nestList;
5507
+ const firstTrailingNestIndex = ancestorNestLists.indexOf(level.trailingNestLists[0]);
5508
+ if (firstTrailingNestIndex >= 0) {
5509
+ const keptNestLists = ancestorNestLists.slice(0, firstTrailingNestIndex);
5510
+ ancestorItem.apply(new ReplaceNestListAction(keptNestLists));
5511
+ }
5512
+ }
5513
+ }
5514
+ rootContainer.apply(new InsertChildrenAfterAction(rootList, ...insertions));
5515
+ }
5516
+ /**
5517
+ * Normalize selected items into document order and split them into contiguous
5518
+ * segments that share the same immediate parent list. Unlike Shift+Tab, the
5519
+ * toolbar action keeps selected descendants so every selected item becomes a
5520
+ * paragraph.
5521
+ *
5522
+ * @param {RTEBlock[]} selectedBlocks - Raw selected blocks.
5523
+ * @returns {RTEListItemBlock[][]} Parent-based contiguous selection segments.
5524
+ */
5525
+ getSelectedSegments(selectedBlocks) {
5526
+ const selectedItems = Array.from(new Set(selectedBlocks.filter((block) => block instanceof RTEListItemBlock)))
5527
+ .map((item) => ({ item, path: this.getStructuralPath(item) }))
5528
+ .filter((entry) => entry.path !== null)
5529
+ .sort((a, b) => this.compareStructuralPaths(a.path, b.path))
5530
+ .map((entry) => entry.item);
5531
+ const segments = [];
5532
+ for (const item of selectedItems) {
5533
+ const segment = segments[segments.length - 1];
5534
+ const previousItem = segment === null || segment === void 0 ? void 0 : segment[segment.length - 1];
5535
+ const isContiguousSibling = (previousItem === null || previousItem === void 0 ? void 0 : previousItem.parent) === item.parent &&
5536
+ item.parent.children.indexOf(item) - item.parent.children.indexOf(previousItem) === 1;
5537
+ if (isContiguousSibling) {
5538
+ segment.push(item);
5539
+ }
5540
+ else {
5541
+ segments.push([item]);
5542
+ }
5543
+ }
5544
+ return segments;
5545
+ }
5546
+ /**
5547
+ * Resolve a list item's structural document path, including the positions of
5548
+ * root lists, owning list items, nested lists, and the item itself.
5549
+ *
5550
+ * @param {RTEListItemBlock} item - Selected list item.
5551
+ * @returns {number[] | null} Structural path, or null for a detached item.
5552
+ */
5553
+ getStructuralPath(item) {
5554
+ var _a;
5555
+ const path = [];
5556
+ const visitedLists = new Set();
5557
+ let currentItem = item;
5558
+ let currentList = item.parent;
5559
+ while (!visitedLists.has(currentList)) {
5560
+ visitedLists.add(currentList);
5561
+ const itemIndex = currentList.children.indexOf(currentItem);
5562
+ if (itemIndex < 0) {
5563
+ return null;
5564
+ }
5565
+ path.unshift(itemIndex);
5566
+ if (currentList.parent.dtoName === 'VegaRTEContent' ||
5567
+ currentList.parent.dtoName === 'RTEHtmlBlock') {
5568
+ const containerPath = this.getContainerPath(currentList);
5569
+ return containerPath ? [...containerPath, ...path] : null;
5570
+ }
5571
+ if (!(currentList.parent instanceof RTEListItemBlock)) {
5572
+ return null;
5573
+ }
5574
+ const ownerItem = currentList.parent;
5575
+ const nestListIndex = ((_a = ownerItem.nestList) !== null && _a !== void 0 ? _a : []).indexOf(currentList);
5576
+ if (nestListIndex < 0) {
5577
+ return null;
5578
+ }
5579
+ path.unshift(nestListIndex);
5580
+ currentItem = ownerItem;
5581
+ currentList = ownerItem.parent;
5582
+ }
5583
+ return null;
5584
+ }
5585
+ /**
5586
+ * Resolve a root list's path through zero or more HTML containers to the
5587
+ * editor content.
5588
+ *
5589
+ * @param {RTEListBlock} rootList - List whose parent is a content container.
5590
+ * @returns {number[] | null} Container path, or null for detached/cyclic ownership.
5591
+ */
5592
+ getContainerPath(rootList) {
5593
+ const path = [];
5594
+ const visitedContainers = new Set();
5595
+ let child = rootList;
5596
+ let container = rootList.parent;
5597
+ while (container instanceof RTEHtmlBlock) {
5598
+ if (visitedContainers.has(container)) {
5599
+ return null;
5600
+ }
5601
+ visitedContainers.add(container);
5602
+ const childIndex = container.children.indexOf(child);
5603
+ if (childIndex < 0) {
5604
+ return null;
5605
+ }
5606
+ path.unshift(childIndex);
5607
+ child = container;
5608
+ container = container.parent;
5609
+ }
5610
+ const rootChildIndex = container.children.indexOf(child);
5611
+ if (rootChildIndex < 0) {
5612
+ return null;
5613
+ }
5614
+ path.unshift(rootChildIndex);
5615
+ return path;
5616
+ }
5617
+ /**
5618
+ * Compare two structural paths in document order.
5619
+ *
5620
+ * @param {number[]} firstPath - First structural path.
5621
+ * @param {number[]} secondPath - Second structural path.
5622
+ * @returns {number} Relative document order.
5623
+ */
5624
+ compareStructuralPaths(firstPath, secondPath) {
5625
+ const length = Math.min(firstPath.length, secondPath.length);
5626
+ for (let index = 0; index < length; index++) {
5627
+ if (firstPath[index] !== secondPath[index]) {
5628
+ return firstPath[index] - secondPath[index];
5629
+ }
5630
+ }
5631
+ return firstPath.length - secondPath.length;
5632
+ }
5633
+ /**
5634
+ * Append a list to an operation-local block sequence, merging only with the
5635
+ * immediately preceding same-type list in that sequence.
5636
+ *
5637
+ * @param {RTEBlock[]} blocks - Operation-local output sequence.
5638
+ * @param {RTEListBlock} list - List to append or merge.
5639
+ */
5640
+ appendListBlock(blocks, list) {
5641
+ const previousBlock = blocks[blocks.length - 1];
5642
+ if (previousBlock instanceof RTEListBlock &&
5643
+ previousBlock.type === list.type &&
5644
+ this.haveSameListAnnotations(previousBlock, list)) {
5645
+ previousBlock.apply(new AppendChildrenAction([...list.children]));
5646
+ return;
5647
+ }
5648
+ blocks.push(list);
5649
+ }
5650
+ /**
5651
+ * Create a list through the content factory and retain the source list's
5652
+ * container annotations when a structural split requires a new list block.
5653
+ *
5654
+ * @param {VegaRTEContent} rootContent - Editor content that owns the factory.
5655
+ * @param {RTEListBlock} source - List whose type and annotations should be retained.
5656
+ * @returns {RTEListBlock} Newly created list shell.
5657
+ */
5658
+ createListFromSource(rootContent, source) {
5659
+ const list = rootContent.createList(source.type);
5660
+ this.copyListAnnotations(source, list);
5661
+ return list;
5662
+ }
5663
+ /**
5664
+ * Converts a RTEListItemBlock to a RTETextBlock representing a paragraph.
5665
+ *
5666
+ * @param {RTEListItemBlock} block - The block that will be covered
5667
+ * @returns {RTETextBlock} Returns a `RTETextBlock`.
5668
+ */
5669
+ toParagraph(block) {
5670
+ const textBlock = new RTETextBlock(misc.generateUUID(), 'paragraph');
5671
+ textBlock.apply(new AppendChildrenAction(block['children']));
5672
+ textBlock['annotationMap'] = block['annotationMap'];
5673
+ return textBlock;
5674
+ }
5675
+ }
5676
+
5677
+ /**
5678
+ * Insert image to list block strategy.
5679
+ */
5680
+ class ListInsertImageStrategy extends ActionHandleStrategy {
5681
+ /**
5682
+ * Insert image block at behind of the list item block.
5683
+ *
5684
+ * @param {InsertImageToBlockAction} action - The insert image action instance.
5685
+ * @param {RTEListBlock} target - The list block.
5686
+ */
5687
+ handleAction(action, target) {
5688
+ const imageBlock = action.imageBlockToBeInserted;
5689
+ if (target.parent['type'] !== 'list-item') {
5690
+ target.parent.apply(new InsertChildrenAfterAction(target, imageBlock));
5691
+ }
5692
+ else {
5693
+ target.parent.apply(action);
5694
+ }
5695
+ }
5696
+ }
5697
+
5698
+ /**
5699
+ * Shared base strategy for list-item operations that require ordered contiguous
5700
+ * item selection within the same target list.
5701
+ */
5702
+ class AbstractListItemsStrategy extends ActionHandleStrategy {
5703
+ /**
5704
+ * Returns selected list items ordered by their position in target and validated
5705
+ * as a contiguous range. Returns an empty array when selection is invalid.
5706
+ *
5707
+ * @param {RTEListBlock} target - The target list block containing selected items.
5708
+ * @param {RTEListItemBlock[]} selectedBlocks - Selected list items from action payload.
5709
+ * @returns {RTEListItemBlock[]} Ordered contiguous selected items, or empty array.
5710
+ */
5711
+ getOrderedContiguousItems(target, selectedBlocks) {
5712
+ const orderedItems = [...selectedBlocks].sort((a, b) => target.children.indexOf(a) - target.children.indexOf(b));
5713
+ const startIndex = target.children.indexOf(orderedItems[0]);
5714
+ if (startIndex < 0) {
5715
+ return [];
5716
+ }
5717
+ return target.children
5718
+ .slice(startIndex, startIndex + orderedItems.length)
5719
+ .every((item, index) => item === orderedItems[index])
5720
+ ? orderedItems
5721
+ : [];
5722
+ }
5723
+ }
5724
+
5725
+ /**
5726
+ * Move selected list items into a nested list under the previous sibling.
5727
+ */
5728
+ class ListNestItemsStrategy extends AbstractListItemsStrategy {
5729
+ /**
5730
+ * @inheritDoc
5731
+ */
5732
+ handleAction(action, target) {
5733
+ var _a, _b;
5734
+ const selectedItems = this.getOrderedContiguousItems(target, action.selectedBlocks);
5735
+ if (!selectedItems.length) {
5736
+ return;
5737
+ }
5738
+ const startIndex = target.children.indexOf(selectedItems[0]);
5739
+ if (startIndex <= 0) {
5740
+ return;
5741
+ }
5742
+ const previousSibling = target.children[startIndex - 1];
5743
+ const selectedItemSet = new Set(selectedItems);
5744
+ // Tab behavior intentionally keeps using the last nested list entry if present,
5745
+ // even when mixed nested-list types exist, to preserve current behavior.
5746
+ // This also matches the behavior of other rich text editors, especially CKEditor.
5747
+ let nestedList = (_a = previousSibling.nestList) === null || _a === void 0 ? void 0 : _a[previousSibling.nestList.length - 1];
5748
+ if (!nestedList) {
5749
+ nestedList = new RTEListBlock(misc.generateUUID(), target.type);
5750
+ previousSibling.apply(new ReplaceNestListAction([...((_b = previousSibling.nestList) !== null && _b !== void 0 ? _b : []), nestedList]));
5751
+ }
5752
+ target.children = target.children.filter((item) => !selectedItemSet.has(item));
5753
+ nestedList.children = nestedList.children.concat(selectedItems);
5754
+ selectedItems.forEach((item) => {
5755
+ var _a;
5756
+ item.parent = nestedList;
5757
+ if ((_a = item.nestList) === null || _a === void 0 ? void 0 : _a.length) {
5758
+ this.unifyDescendantNestLists(item, item.nestList[0].type);
5759
+ }
5760
+ item.children.forEach((node) => node.apply(new SyncUpSelectionAction()));
5761
+ });
5762
+ }
5763
+ /**
5764
+ * Recursively unify all nestLists of a list item (and its descendants) to the given type.
5765
+ * Adjacent same-type merge is handled automatically by ListItemReplaceNestListStrategy
5766
+ * when ReplaceNestListAction is applied, so this method only needs to set the type.
5767
+ *
5768
+ * @param {RTEListItemBlock} item - The list item whose descendants should be normalized.
5769
+ * @param {RTEListBlock['type']} targetType - The target list type used for normalization.
5770
+ */
5771
+ unifyDescendantNestLists(item, targetType) {
5772
+ var _a;
5773
+ if (!((_a = item.nestList) === null || _a === void 0 ? void 0 : _a.length)) {
5774
+ return;
5775
+ }
5776
+ let typeChanged = false;
5777
+ for (const list of item.nestList) {
5778
+ if (list.type !== targetType) {
5779
+ list.type = targetType;
5780
+ typeChanged = true;
5781
+ }
5782
+ // Recursively unify children
5783
+ for (const child of list.children) {
5784
+ this.unifyDescendantNestLists(child, targetType);
5785
+ }
5786
+ }
5787
+ // If any type was changed, re-apply through ReplaceNestListAction so that the
5788
+ // centralized normalize in ListItemReplaceNestListStrategy merges adjacent same-type entries.
5789
+ if (typeChanged) {
5790
+ item.apply(new ReplaceNestListAction([...item.nestList]));
5791
+ }
5792
+ }
5793
+ }
5794
+
5795
+ /**
5796
+ * Delete the nest list block action
5797
+ *
5798
+ * @example needRemovedNestList.parent.apply(new RemoveNestListAction(needRemovedNestList))
5799
+ */
5800
+ class RemoveNestListAction extends ModifyContentAction {
5801
+ constructor(childList) {
5802
+ super();
5803
+ this.type = exports.ModifyContentActionType.DELETE_NEST_LIST;
5804
+ this.nestListBlockToBeRemoved = childList;
5805
+ }
5806
+ }
5807
+
5808
+ /**
5809
+ * Promote selected nested list items one level up.
5810
+ */
5811
+ class ListUnnestItemsStrategy extends AbstractListItemsStrategy {
5812
+ /**
5813
+ * @inheritDoc
5814
+ */
5815
+ handleAction(action, target) {
5816
+ var _a;
5817
+ const selectedItems = this.getOrderedContiguousItems(target, action.selectedBlocks);
5818
+ const parentListParent = target.parent;
5819
+ if (!selectedItems.length || !(parentListParent instanceof RTEListItemBlock)) {
5820
+ return;
5821
+ }
5822
+ const selectedStartIndex = target.children.indexOf(selectedItems[0]);
5823
+ const selectedEndIndex = target.children.indexOf(selectedItems[selectedItems.length - 1]);
5824
+ if (selectedStartIndex < 0 || selectedEndIndex < selectedStartIndex) {
5825
+ return;
5826
+ }
5827
+ const parentListItem = parentListParent;
5828
+ const grandParentList = parentListItem.parent;
5829
+ const insertAfterIndex = grandParentList.children.indexOf(parentListItem);
5830
+ if (insertAfterIndex < 0) {
5831
+ return;
5832
+ }
5833
+ const trailingSiblingItems = target.children.slice(selectedEndIndex + 1);
5834
+ const selectedItemSet = new Set(selectedItems);
5835
+ target.children = target.children.filter((item) => !selectedItemSet.has(item));
5836
+ grandParentList.children = [
5837
+ ...grandParentList.children.slice(0, insertAfterIndex + 1),
5838
+ ...selectedItems,
5839
+ ...grandParentList.children.slice(insertAfterIndex + 1),
5840
+ ];
5841
+ selectedItems.forEach((item) => {
5842
+ item.parent = grandParentList;
5843
+ item.children.forEach((node) => node.apply(new SyncUpSelectionAction()));
5844
+ });
5845
+ if (trailingSiblingItems.length > 0) {
5846
+ const trailingSiblingSet = new Set(trailingSiblingItems);
5847
+ target.children = target.children.filter((item) => !trailingSiblingSet.has(item));
5848
+ const newParentItem = selectedItems[selectedItems.length - 1];
5849
+ let nestedList = (_a = newParentItem.nestList) === null || _a === void 0 ? void 0 : _a[newParentItem.nestList.length - 1];
5850
+ // Shift+Tab follows same-type guard: when the last nested list has a
5851
+ // different type, create a new child list of target.type instead of merging.
5852
+ if (nestedList && nestedList.type !== target.type) {
5853
+ nestedList = null;
5854
+ }
5855
+ if (!nestedList) {
5856
+ nestedList = new RTEListBlock(misc.generateUUID(), target.type);
5857
+ const existingNestLists = Array.isArray(newParentItem.nestList)
5858
+ ? newParentItem.nestList
5859
+ : [];
5860
+ newParentItem.apply(new ReplaceNestListAction([...existingNestLists, nestedList]));
5861
+ }
5862
+ nestedList.children = nestedList.children.concat(trailingSiblingItems);
5863
+ trailingSiblingItems.forEach((item) => {
5864
+ item.parent = nestedList;
5865
+ });
5866
+ }
5867
+ // Lists after target are visually after every target item. Once selected items
5868
+ // move above their former parent, transfer those later branches to the last
5869
+ // selected item even when target still contains leading items; otherwise the
5870
+ // branches render before the promoted selection and document order changes.
5871
+ const trailingNestLists = this.collectTrailingNestLists(parentListItem, target);
5872
+ if (trailingNestLists.length > 0) {
5873
+ const lastSelected = selectedItems[selectedItems.length - 1];
5874
+ const existingNest = Array.isArray(lastSelected.nestList)
5875
+ ? lastSelected.nestList
5876
+ : [];
5877
+ lastSelected.apply(new ReplaceNestListAction([...existingNest, ...trailingNestLists]));
5878
+ }
5879
+ if (target.children.length === 0) {
5880
+ parentListItem.apply(new RemoveNestListAction(target));
5881
+ }
5882
+ }
5883
+ /**
5884
+ * Collect and remove nestList entries that appear after the given target list
5885
+ * in the parent item's nestList array. These trailing entries need to be
5886
+ * transferred to the unnested item to preserve visual document order.
5887
+ *
5888
+ * @param {RTEListItemBlock} parentListItem - The list item owning the nestList.
5889
+ * @param {RTEListBlock} target - The list being removed (used as the reference point).
5890
+ * @returns {RTEListBlock[]} The trailing nestList entries (already removed from parentListItem).
5891
+ */
5892
+ collectTrailingNestLists(parentListItem, target) {
5893
+ var _a;
5894
+ const nestLists = (_a = parentListItem.nestList) !== null && _a !== void 0 ? _a : [];
5895
+ const targetIndex = nestLists.indexOf(target);
5896
+ if (targetIndex < 0 || targetIndex >= nestLists.length - 1) {
5897
+ return [];
5898
+ }
5899
+ const trailing = nestLists.slice(targetIndex + 1);
5900
+ // Keep only entries up to and including target (target will be removed separately).
5901
+ parentListItem.apply(new ReplaceNestListAction(nestLists.slice(0, targetIndex + 1)));
5902
+ return trailing;
5903
+ }
5904
+ }
5905
+
5906
+ /**
5907
+ * List annotation
5908
+ */
5909
+ class ListAnnotation extends BlockAnnotation {
5910
+ constructor() {
5911
+ super(...arguments);
5912
+ this.type = exports.BlockAnnotationTypeEnum.LIST;
5913
+ }
5914
+ /**
5915
+ * Get the default standalone styles for a list block.
5916
+ *
5917
+ * @returns {AnnotationStyle} The default styles.
5918
+ */
5919
+ static getDefaultStyles() {
5920
+ return {
5921
+ paddingLeft: '8px',
5922
+ marginLeft: '16px',
5923
+ };
5924
+ }
5925
+ /**
5926
+ * Get the default standalone styles for a list block's item marker
5927
+ * (`li::marker`). Capping the marker font-size keeps bullets/numbers
5928
+ * at a normal size when list items are styled as title/subtitle.
5929
+ *
5930
+ * @returns {AnnotationStyle} The default marker styles.
5931
+ */
5932
+ static getDefaultMarkerStyles() {
5933
+ return {
5934
+ fontSize: '16px',
5935
+ };
5936
+ }
5937
+ /**
5938
+ * @inheritDoc
5939
+ */
5940
+ renderStyle(options) {
5941
+ if (!(options === null || options === void 0 ? void 0 : options.standalone))
5942
+ return null;
5943
+ return ListAnnotation.getDefaultStyles();
5944
+ }
5945
+ /**
5946
+ * @inheritDoc
5947
+ */
5948
+ renderClass(options) {
5949
+ if (options === null || options === void 0 ? void 0 : options.standalone)
5950
+ return null;
5951
+ return 'v-rte--list';
5952
+ }
5953
+ /**
5954
+ * @inheritDoc
5955
+ */
5956
+ clone() {
5957
+ return new ListAnnotation();
5958
+ }
5959
+ /**
5960
+ * @inheritDoc
5961
+ */
5962
+ toJSON() {
5963
+ return undefined;
5964
+ }
5965
+ }
5966
+
5967
+ /**
5968
+ * List block.
5969
+ *
5970
+ * Bidirectional nesting contract:
5971
+ * - Every child list item must have item.parent === this list block.
5972
+ * - If this list block is nested, its parent must be a list item and that
5973
+ * list item keeps this block in listItem.nestList.
5974
+ */
5975
+ class RTEListBlock extends RTEBlock {
5976
+ constructor(id, type, options) {
5977
+ super(id);
5978
+ this.dtoName = RTEListBlock.dtoName;
5979
+ this.type = 'bullet-list';
5980
+ this.children = [];
5981
+ this.type = type;
5982
+ const { autoMatchFormat } = options || { autoMatchFormat: true };
5983
+ if (autoMatchFormat) {
5984
+ this.annotationMap.set(exports.BlockAnnotationTypeEnum.LIST, new ListAnnotation());
5985
+ }
5986
+ }
5987
+ /**
5988
+ * Converts a VegaRTEListBlock object to an RTEListBlock
5989
+ *
5990
+ * @param {VegaRTEListBlock} block - Converts a `VegaRTEListBlock` object into an `RTEListBlock`.
5991
+ * @param {VegaRTETransformOptions} options - Optional transformation options.
5992
+ * @returns {RTEListBlock} Return an instance of `RTEListBlock`
5993
+ */
5994
+ static from(block, options = { autoMatchFormat: true }) {
5995
+ const listBlock = new RTEListBlock(block.id, block.type, options);
5996
+ const { annotations } = block;
5997
+ if (annotations) {
5998
+ Object.entries(annotations).forEach(([type, value]) => {
5999
+ const item = this.createAnnotationEntity(type, value);
6000
+ if (typeGuard.isNonNullable(item)) {
6001
+ listBlock.annotationMap.set(...item);
6002
+ }
6003
+ });
6004
+ }
6005
+ listBlock.children = block.blocks.map((item) => {
6006
+ const listItemBlock = RTEListItemBlock.from(item, options);
6007
+ listItemBlock.parent = listBlock;
6008
+ return listItemBlock;
6009
+ });
6010
+ return listBlock;
6011
+ }
6012
+ /**
6013
+ * The function `createAnnotationEntity` creates a block annotation entity based on the provided type
6014
+ * and value.
6015
+ *
6016
+ * @param {keyof VegaRTEBlockAnnotations} type - The `type` parameter is a key of the `VegaRTEBlockAnnotations` enum, which specifies
6017
+ * the type of annotation entity to create.
6018
+ * @param {unknown} value - The `value` parameter in the `createAnnotationEntity` function is the value
6019
+ * that will be used to create the annotation entity. It can be of any type depending on the specific
6020
+ * annotation being created.
6021
+ * @returns {Nullable<BlockAnnotationsEntity>} The `createAnnotationEntity` function returns a nullable tuple containing a
6022
+ * `BlockAnnotationTypeEnum` and a `BlockAnnotation` object.
6023
+ */
6024
+ static createAnnotationEntity(type, value) {
6025
+ switch (type) {
6026
+ case 'customAttribute':
6027
+ return CustomAttributeAnnotation.from(value);
6028
+ case 'customClass':
6029
+ return CustomClassAnnotation.from(value);
6030
+ case 'customStyle':
6031
+ return CustomStyleAnnotation.from(value);
6032
+ }
6033
+ }
6034
+ /**
6035
+ * @inheritDoc
6036
+ */
6037
+ toJSON() {
6038
+ return Object.assign(Object.assign({}, super.toJSON()), { id: this.id, type: this.type, blocks: this.children.map((block) => block.toJSON()) });
6039
+ }
6040
+ /**
6041
+ * @inheritDoc
6042
+ */
6043
+ toHtml(options) {
6044
+ const BlockTag = this.getBlockTag();
6045
+ const attrStr = super.generateAttributeString(options);
6046
+ return [
6047
+ `<${BlockTag}${attrStr}>`,
6048
+ this.children.map((block) => block.toHtml(options)).join(''),
6049
+ `</${BlockTag}>`,
6050
+ ].join('');
6051
+ }
6052
+ /**
6053
+ * @inheritDoc
6054
+ */
6055
+ isNotEmpty() {
6056
+ return this.children.length > 0;
6057
+ }
6058
+ /**
6059
+ * @inheritDoc
6060
+ */
6061
+ getLastNode() {
6062
+ return this.children[this.children.length - 1].getLastNode();
6063
+ }
6064
+ /**
6065
+ * @inheritDoc
6066
+ */
6067
+ clone(parent) {
6068
+ const clonedListBlock = new RTEListBlock(this.id, this.type);
6069
+ clonedListBlock.children = this.children.map((item) => item.clone(clonedListBlock));
6070
+ clonedListBlock.annotationMap = super.cloneAnnotations();
6071
+ clonedListBlock.parent = parent;
6072
+ return clonedListBlock;
6073
+ }
6074
+ /**
6075
+ * Returns the block tag based on the type of the list block.
6076
+ *
6077
+ * @returns {RTEListBlockTagType} - The block tag for the list block, either 'ol' or 'ul'.
6078
+ */
6079
+ getBlockTag() {
6080
+ return this.type === 'number-list' ? 'ol' : 'ul';
6081
+ }
6082
+ }
6083
+ (() => {
6084
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.TRANSFORM_LIST_BLOCK, RTEListBlock.name, new ListTransformToListStrategy());
6085
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.TRANSFORM_PARAGRAPH_BLOCK, RTEListBlock.name, new ListTransformToParagraphStrategy());
6086
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.INSERT_IMAGE_TO_BLOCK, RTEListBlock.name, new ListInsertImageStrategy());
6087
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.NEST_LIST_ITEMS, RTEListBlock.name, new ListNestItemsStrategy());
6088
+ ActionHandleStrategyRegistry.register(exports.ModifyContentActionType.UNNEST_LIST_ITEMS, RTEListBlock.name, new ListUnnestItemsStrategy());
6089
+ })();
6090
+ RTEListBlock.dtoName = 'RTEListBlock';
6091
+
6092
+ /**
6093
+ * The delete node content contains some common functions that used for image block delete the image node or text block delete text node.
6094
+ */
6095
+ class BlockDeleteNodeContentStrategy extends ActionHandleStrategy {
6096
+ /**
6097
+ * Returns the previous node relative to the current node in a rich text editor structure.
6098
+ *
6099
+ * @param {RTENode} currentNode - An object of type `RTENode`.
6100
+ * @returns {Nullable<RTENode>} the previous block last node
6101
+ */
6102
+ getPreviousNode(currentNode) {
6103
+ var _a;
6104
+ const currentBlock = currentNode.parent;
6105
+ const currentIndex = currentBlock.children.indexOf(currentNode);
6106
+ if (currentIndex > 0) {
6107
+ return currentBlock.children[currentIndex - 1];
6108
+ }
6109
+ else if (currentBlock.parent) {
6110
+ // Special case: cursor is at the start of the first item in a nested list.
6111
+ // Return the last direct text node of the grandparent list item so that
6112
+ // Backspace correctly merges the nested item into the parent item rather
6113
+ // than descending into the nested list's own descendants.
6114
+ if (currentBlock.isListItemBlock() &&
6115
+ currentBlock.parent.children.indexOf(currentBlock) === 0 &&
6116
+ currentBlock.parent.parent instanceof RTEListItemBlock) {
6117
+ const grandParentItem = currentBlock.parent.parent;
6118
+ const nestedListIndex = ((_a = grandParentItem.nestList) !== null && _a !== void 0 ? _a : []).indexOf(currentBlock.parent);
6119
+ if (nestedListIndex !== 0) {
6120
+ const previousBlock = this.getPreviousBlock(currentBlock);
6121
+ return previousBlock ? this.getBlockLastNode(previousBlock) : null;
6122
+ }
6123
+ const textNodes = grandParentItem.children;
6124
+ return textNodes.length > 0 ? textNodes[textNodes.length - 1] : null;
6125
+ }
6126
+ const previousBlock = this.getPreviousBlock(currentBlock);
6127
+ if (previousBlock) {
6128
+ return this.getBlockLastNode(previousBlock);
6129
+ }
6130
+ }
6131
+ }
6132
+ /**
6133
+ * Returns the next node relative to the current node in a rich text editor structure.
6134
+ *
6135
+ * @param {RTENode} currentNode - An object of type `RTENode`.
6136
+ * @returns {Nullable<RTENode>} the next block first node
6137
+ */
6138
+ getNextNode(currentNode) {
6139
+ const currentBlock = currentNode.parent;
6140
+ const currentIndex = currentBlock.children.indexOf(currentNode);
6141
+ if (currentBlock.children[currentIndex + 1]) {
6142
+ return currentBlock.children[currentIndex + 1];
6143
+ }
6144
+ else if (currentBlock.parent) {
6145
+ const nextBlock = this.getNextBlock(currentBlock);
6146
+ if (nextBlock) {
6147
+ return this.getBlockFirstNode(nextBlock);
6148
+ }
6149
+ }
6150
+ }
6151
+ /**
6152
+ * Determines if a given node is the first node within the current state.
6153
+ *
6154
+ * @param {RTENode} currentNode - An object representing a node in a rich text editor (RTE).
6155
+ * @returns {boolean} True or false;
6156
+ */
6157
+ isContentFirstNode(currentNode) {
6158
+ const currentBlock = currentNode.parent;
6159
+ const currentIndex = currentBlock.children.indexOf(currentNode);
6160
+ const parent = currentBlock.parent;
6161
+ if (currentBlock.isListItemBlock()) {
6162
+ const listParent = parent.parent;
6163
+ return (currentIndex === 0 &&
6164
+ Array.isArray(parent.children) &&
6165
+ parent.children[0] === currentBlock &&
6166
+ listParent['type'] !== 'list-item' &&
6167
+ Array.isArray(listParent.children) &&
6168
+ listParent.children[0] === parent);
6169
+ }
6170
+ else {
6171
+ return (currentIndex === 0 && Array.isArray(parent.children) && parent.children[0] === currentBlock);
6172
+ }
6173
+ }
6174
+ /**
6175
+ * TODO: The getPreviousBlock add nest list support
6176
+ * This function retrieves the previous block in a rich text editor, considering different scenarios such as being in a bullet list.
6177
+ *
6178
+ * @param {RTEBlock} currentBlock - Used to retrieve the previous block relative to the given `currentBlock` within a rich text editor context.
6179
+ * @returns {Nullable<RTEBlock>} The previous block if existing
6180
+ */
6181
+ getPreviousBlock(currentBlock) {
6182
+ var _a;
6183
+ if (currentBlock.parent instanceof RTEListItemBlock) {
6184
+ const nestedLists = (_a = currentBlock.parent.nestList) !== null && _a !== void 0 ? _a : [];
6185
+ const nestedListIndex = nestedLists.indexOf(currentBlock);
6186
+ if (nestedListIndex > 0) {
6187
+ return nestedLists[nestedListIndex - 1];
6188
+ }
6189
+ if (nestedListIndex === 0) {
6190
+ return currentBlock.parent;
6191
+ }
6192
+ }
4749
6193
  if (currentBlock && currentBlock.parent && currentBlock.parent.children) {
4750
6194
  const currentBlockIndex = currentBlock.parent.children.indexOf(currentBlock);
4751
6195
  if (currentBlockIndex > 0) {
@@ -5326,13 +6770,9 @@ exports.BOLD_FONT_WEIGHT = BOLD_FONT_WEIGHT;
5326
6770
  exports.BOLD_FONT_WEIGHT_KEYWORD = BOLD_FONT_WEIGHT_KEYWORD;
5327
6771
  exports.BlockAnnotation = BlockAnnotation;
5328
6772
  exports.BlockDeleteNodeContentStrategy = BlockDeleteNodeContentStrategy;
5329
- exports.BlockInsertLineBreakStrategy = BlockInsertLineBreakStrategy;
5330
- exports.BlockInsertLineBreakWithBlocksStrategy = BlockInsertLineBreakWithBlocksStrategy;
5331
6773
  exports.BlockMergeNodesStrategy = BlockMergeNodesStrategy;
5332
6774
  exports.BlockReplaceNodesStrategy = BlockReplaceNodesStrategy;
5333
- exports.BlockSplitWithTextNodeStrategy = BlockSplitWithTextNodeStrategy;
5334
6775
  exports.BlockUpdateHorizontalAlignmentStrategy = BlockUpdateHorizontalAlignmentStrategy;
5335
- exports.BlockUpdateTextStyleStrategy = BlockUpdateTextStyleStrategy;
5336
6776
  exports.BoldAnnotation = BoldAnnotation;
5337
6777
  exports.BoldAnnotationAction = BoldAnnotationAction;
5338
6778
  exports.ClearFormattingAnnotationAction = ClearFormattingAnnotationAction;
@@ -5344,7 +6784,6 @@ exports.CommonAnnotation = CommonAnnotation;
5344
6784
  exports.CustomAttributeAnnotation = CustomAttributeAnnotation;
5345
6785
  exports.CustomClassAnnotation = CustomClassAnnotation;
5346
6786
  exports.CustomStyleAnnotation = CustomStyleAnnotation;
5347
- exports.HTML_VOID_TAGS = HTML_VOID_TAGS;
5348
6787
  exports.HorizontalAlignmentAnnotation = HorizontalAlignmentAnnotation;
5349
6788
  exports.HorizontalAlignmentAnnotationAction = HorizontalAlignmentAnnotationAction;
5350
6789
  exports.ITALIC_FONT_STYLE = ITALIC_FONT_STYLE;
@@ -5354,6 +6793,7 @@ exports.InsertChildrenBeforeAction = InsertChildrenBeforeAction;
5354
6793
  exports.ItalicAnnotationAction = ItalicAnnotationAction;
5355
6794
  exports.LinkAnnotationAction = LinkAnnotationAction;
5356
6795
  exports.LinkFilterStylesStrategy = LinkFilterStylesStrategy;
6796
+ exports.ListAnnotation = ListAnnotation;
5357
6797
  exports.ModifyContentAction = ModifyContentAction;
5358
6798
  exports.NodeAnnotation = NodeAnnotation;
5359
6799
  exports.Predicate = Predicate;
@@ -5365,6 +6805,9 @@ exports.RTEDTOClassManager = RTEDTOClassManager$1;
5365
6805
  exports.RTEDecoratorNode = RTEDecoratorNode;
5366
6806
  exports.RTEFilterStylesStrategy = RTEFilterStylesStrategy;
5367
6807
  exports.RTEFilterStylesStrategyRegistry = RTEFilterStylesStrategyRegistry;
6808
+ exports.RTEHtmlBlock = RTEHtmlBlock;
6809
+ exports.RTEListBlock = RTEListBlock;
6810
+ exports.RTEListItemBlock = RTEListItemBlock;
5368
6811
  exports.RTENode = RTENode;
5369
6812
  exports.RTETextBlock = RTETextBlock;
5370
6813
  exports.RTETextNode = RTETextNode;
@@ -5372,7 +6815,9 @@ exports.RTE_DEFAULT_TEXT_COLOR = RTE_DEFAULT_TEXT_COLOR;
5372
6815
  exports.RTE_TEXT_COLORS = RTE_TEXT_COLORS;
5373
6816
  exports.RemoveChildrenAction = RemoveChildrenAction;
5374
6817
  exports.RemoveChildrenStrategy = RemoveChildrenStrategy;
6818
+ exports.RemoveNestListAction = RemoveNestListAction;
5375
6819
  exports.ReplaceChildNodesAction = ReplaceChildNodesAction;
6820
+ exports.ReplaceNestListAction = ReplaceNestListAction;
5376
6821
  exports.STRIKETHROUGH_TEXT_DECORATION = STRIKETHROUGH_TEXT_DECORATION;
5377
6822
  exports.SelectionChangeAction = SelectionChangeAction;
5378
6823
  exports.SplitBlockWithNodeAction = SplitBlockWithNodeAction;
@@ -5381,6 +6826,7 @@ exports.SyncUpSelectionAction = SyncUpSelectionAction;
5381
6826
  exports.TextColorAnnotationAction = TextColorAnnotationAction;
5382
6827
  exports.TextStyleAnnotation = TextStyleAnnotation;
5383
6828
  exports.TextStyleAnnotationAction = TextStyleAnnotationAction;
6829
+ exports.TransformParagraphAction = TransformParagraphAction;
5384
6830
  exports.UNDERLINE_TEXT_DECORATION = UNDERLINE_TEXT_DECORATION;
5385
6831
  exports.UnderlineAnnotationAction = UnderlineAnnotationAction;
5386
6832
  exports.UpdateCodeBlockAction = UpdateCodeBlockAction;