@heartlandone/vega 2.95.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 (181) hide show
  1. package/dist/cjs/{app-globals-76815382.js → app-globals-38afea36.js} +7 -7
  2. package/dist/cjs/{code-block-493c7ce7.js → code-block-4126dc3b.js} +1501 -55
  3. package/dist/cjs/{component-value-history-controller-slimmer.abstract-ab21fcbf.js → component-value-history-controller-slimmer.abstract-38ba956e.js} +2 -2
  4. package/dist/cjs/{content-state-fc34a814.js → content-state-50e8a03c.js} +142 -580
  5. package/dist/cjs/{element-appender-slimmer-1d6323c2.js → element-appender-slimmer-7773fdab.js} +115 -0
  6. package/dist/cjs/{image-annotation-action-7c4cd316.js → image-annotation-action-89363de8.js} +2 -2
  7. package/dist/cjs/{image-extension-30a7c10f.js → image-extension-c881c454.js} +2 -2
  8. package/dist/cjs/index.cjs.js +10 -10
  9. package/dist/cjs/{link-extension-92a63cb7.js → link-extension-b7f99a52.js} +2 -2
  10. package/dist/cjs/loader.cjs.js +7 -7
  11. package/dist/cjs/{public-rules-9e1ea1d9.js → public-rules-72894208.js} +3 -3
  12. package/dist/cjs/{range-30219330.js → range-95d41dea.js} +1 -1
  13. package/dist/cjs/{rich-text-editor-required-rule-23bf7485.js → rich-text-editor-required-rule-4d6d2493.js} +1 -1
  14. package/dist/cjs/{split-cell-operation-43752212.js → split-cell-operation-70be116d.js} +2 -2
  15. package/dist/cjs/{token-extension-d123d9d0.js → token-extension-eb828948.js} +35 -11
  16. package/dist/cjs/vega-code-block.cjs.entry.js +3 -3
  17. package/dist/cjs/vega-date-picker_2.cjs.entry.js +1 -1
  18. package/dist/cjs/vega-dropdown_5.cjs.entry.js +27 -4
  19. package/dist/cjs/vega-env-manager-23b8b23c.js +2 -2
  20. package/dist/cjs/vega-popover_2.cjs.entry.js +1 -1
  21. package/dist/cjs/vega-rich-text-content.cjs.entry.js +58 -9
  22. package/dist/cjs/vega-rich-text-editor_4.cjs.entry.js +608 -90
  23. package/dist/cjs/vega-rich-text-table-properties_3.cjs.entry.js +3 -3
  24. package/dist/cjs/vega-section-title.cjs.entry.js +896 -14
  25. package/dist/cjs/vega-time-picker_2.cjs.entry.js +1 -1
  26. package/dist/cjs/vega-tooltip_2.cjs.entry.js +1 -1
  27. package/dist/cjs/vega.cjs.js +7 -7
  28. package/dist/collection/components/vega-combo-box/vega-combo-box.js +2 -2
  29. package/dist/collection/components/vega-dropdown/vega-dropdown.js +30 -7
  30. package/dist/collection/components/vega-input-select/vega-input-select.js +2 -2
  31. package/dist/collection/components/vega-rich-text-content/vega-rich-text-content.css +4 -0
  32. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-delete-node-content-strategy.js +29 -0
  33. 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
  34. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-transform-to-list-strategy.js +8 -3
  35. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.js +60 -0
  36. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-item-replace-nest-list-strategy.js +36 -4
  37. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.js +27 -0
  38. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.js +74 -0
  39. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.js +81 -1
  40. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.js +30 -0
  41. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.js +160 -9
  42. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.js +376 -10
  43. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.js +104 -0
  44. package/dist/collection/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.js +2 -0
  45. package/dist/collection/components/vega-rich-text-editor/dto/actions/nest-list-items-action.js +12 -0
  46. package/dist/collection/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.js +12 -0
  47. package/dist/collection/components/vega-rich-text-editor/dto/annotations/list-annotation.js +12 -0
  48. package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-block.js +10 -1
  49. package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-item-block.js +11 -3
  50. package/dist/collection/components/vega-rich-text-editor/dto/content-state.js +7 -1
  51. package/dist/collection/components/vega-rich-text-editor/dto/filter-styles-strategies/list-block/list-block-filter-styles-strategy.js +8 -4
  52. package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.js +34 -1
  53. package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.js +20 -3
  54. package/dist/collection/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.js +25 -1
  55. 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
  56. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/abstract-delete-content-handler.js +29 -0
  57. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.js +30 -1
  58. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.js +204 -0
  59. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.js +42 -0
  60. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.js +34 -0
  61. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.js +180 -0
  62. package/dist/collection/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.js +54 -0
  63. package/dist/collection/components/vega-section-title/slimmers/renderers/vega-section-title-renderer.js +4 -4
  64. package/dist/collection/components/vega-section-title/vega-section-title.js +18 -2
  65. package/dist/collection/helpers/a11y-tree/a11y-node-dto.js +210 -0
  66. package/dist/collection/helpers/a11y-tree/a11y-tree-applier.js +189 -0
  67. package/dist/collection/helpers/a11y-tree/a11y-tree.types.js +48 -0
  68. package/dist/collection/helpers/a11y-tree/strategies/baseline-strategy.js +78 -0
  69. package/dist/collection/helpers/a11y-tree/strategies/firefox-nvda-strategy.js +56 -0
  70. package/dist/collection/helpers/a11y-tree/strategies/webkit-voiceover-strategy.js +140 -0
  71. package/dist/collection/helpers/a11y-tree/strategy-resolver.js +172 -0
  72. package/dist/collection/helpers/slimmers/a11y-tree-slimmer.js +54 -0
  73. package/dist/collection/helpers/slimmers/element-appender/element-appender-slimmer.js +29 -0
  74. package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.js +70 -0
  75. package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.js +1 -0
  76. package/dist/collection/helpers/ui/element-appender.js +16 -0
  77. package/dist/esm/{app-globals-eafcc7a1.js → app-globals-d7b651c1.js} +7 -7
  78. package/dist/esm/{code-block-e12588fe.js → code-block-0a88b481.js} +1495 -51
  79. package/dist/esm/{component-value-history-controller-slimmer.abstract-4e8eb313.js → component-value-history-controller-slimmer.abstract-6846edfa.js} +2 -2
  80. package/dist/esm/{content-state-8032467a.js → content-state-79ca99e5.js} +105 -541
  81. package/dist/esm/{element-appender-slimmer-7fcb944b.js → element-appender-slimmer-73ad10ae.js} +115 -0
  82. package/dist/esm/{image-annotation-action-08a20d5e.js → image-annotation-action-bb299ef1.js} +2 -2
  83. package/dist/esm/{image-extension-b6c7e4a7.js → image-extension-48a96f98.js} +2 -2
  84. package/dist/esm/index.js +8 -8
  85. package/dist/esm/{link-extension-97fcb8fb.js → link-extension-09534514.js} +2 -2
  86. package/dist/esm/loader.js +7 -7
  87. package/dist/esm/{public-rules-c06f0d2a.js → public-rules-5eb03ef0.js} +3 -3
  88. package/dist/esm/{range-e999837f.js → range-d4deb7df.js} +1 -1
  89. package/dist/esm/{rich-text-editor-required-rule-71f8ee98.js → rich-text-editor-required-rule-5bbbce23.js} +1 -1
  90. package/dist/esm/{split-cell-operation-359f8082.js → split-cell-operation-7f3058ad.js} +2 -2
  91. package/dist/esm/{token-extension-f5bf9c21.js → token-extension-40c32bcc.js} +30 -6
  92. package/dist/esm/vega-code-block.entry.js +3 -3
  93. package/dist/esm/vega-date-picker_2.entry.js +1 -1
  94. package/dist/esm/vega-dropdown_5.entry.js +27 -4
  95. package/dist/esm/vega-env-manager-8f8dc473.js +2 -2
  96. package/dist/esm/vega-popover_2.entry.js +1 -1
  97. package/dist/esm/vega-rich-text-content.entry.js +58 -9
  98. package/dist/esm/vega-rich-text-editor_4.entry.js +604 -86
  99. package/dist/esm/vega-rich-text-table-properties_3.entry.js +3 -3
  100. package/dist/esm/vega-section-title.entry.js +897 -15
  101. package/dist/esm/vega-time-picker_2.entry.js +1 -1
  102. package/dist/esm/vega-tooltip_2.entry.js +1 -1
  103. package/dist/esm/vega.js +7 -7
  104. package/dist/sri/vega-sri-manifest.json +94 -94
  105. package/dist/types/components/vega-combo-box/vega-combo-box.d.ts +6 -6
  106. package/dist/types/components/vega-dropdown/types.d.ts +2 -2
  107. package/dist/types/components/vega-dropdown/vega-dropdown.d.ts +32 -9
  108. package/dist/types/components/vega-input-select/vega-input-select.d.ts +6 -6
  109. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.d.ts +36 -0
  110. 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
  111. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.d.ts +22 -0
  112. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.d.ts +21 -0
  113. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.d.ts +14 -0
  114. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.d.ts +15 -0
  115. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.d.ts +30 -3
  116. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.d.ts +99 -3
  117. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.d.ts +22 -0
  118. package/dist/types/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.d.ts +2 -0
  119. package/dist/types/components/vega-rich-text-editor/dto/actions/nest-list-items-action.d.ts +11 -0
  120. package/dist/types/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.d.ts +11 -0
  121. package/dist/types/components/vega-rich-text-editor/dto/annotations/list-annotation.d.ts +8 -0
  122. package/dist/types/components/vega-rich-text-editor/dto/blocks/list-block.d.ts +6 -1
  123. package/dist/types/components/vega-rich-text-editor/dto/blocks/list-item-block.d.ts +5 -1
  124. package/dist/types/components/vega-rich-text-editor/dto/content-state.d.ts +2 -2
  125. package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.d.ts +2 -0
  126. package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.d.ts +8 -0
  127. package/dist/types/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.d.ts +18 -0
  128. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.d.ts +8 -0
  129. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.d.ts +99 -0
  130. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.d.ts +15 -0
  131. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.d.ts +15 -0
  132. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.d.ts +73 -0
  133. package/dist/types/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.d.ts +41 -0
  134. package/dist/types/components/vega-section-title/vega-section-title.d.ts +9 -0
  135. package/dist/types/components.d.ts +10 -10
  136. package/dist/types/helpers/a11y-tree/a11y-node-dto.d.ts +173 -0
  137. package/dist/types/helpers/a11y-tree/a11y-tree-applier.d.ts +28 -0
  138. package/dist/types/helpers/a11y-tree/a11y-tree.types.d.ts +137 -0
  139. package/dist/types/helpers/a11y-tree/strategies/baseline-strategy.d.ts +18 -0
  140. package/dist/types/helpers/a11y-tree/strategies/firefox-nvda-strategy.d.ts +16 -0
  141. package/dist/types/helpers/a11y-tree/strategies/webkit-voiceover-strategy.d.ts +23 -0
  142. package/dist/types/helpers/a11y-tree/strategy-resolver.d.ts +59 -0
  143. package/dist/types/helpers/slimmers/a11y-tree-slimmer.d.ts +49 -0
  144. package/dist/types/helpers/slimmers/element-appender/element-appender-slimmer.d.ts +9 -0
  145. package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.d.ts +37 -0
  146. package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.d.ts +56 -0
  147. package/dist/types/helpers/ui/element-appender.d.ts +7 -0
  148. package/dist/vega/index.esm.js +1 -1
  149. package/dist/vega/{p-9c39f90b.entry.js → p-1dfbc542.entry.js} +1 -1
  150. package/dist/vega/{p-e235020b.entry.js → p-22cc174e.entry.js} +1 -1
  151. package/dist/vega/{p-b187b82d.entry.js → p-2df5d59b.entry.js} +1 -1
  152. package/dist/vega/{p-f7e459cd.js → p-312d8205.js} +1 -1
  153. package/dist/vega/{p-a7209700.js → p-3345d903.js} +1 -1
  154. package/dist/vega/{p-02355de8.js → p-3c23ec90.js} +1 -1
  155. package/dist/vega/p-55e0014a.js +3 -0
  156. package/dist/vega/p-5f377954.js +1 -1
  157. package/dist/vega/p-65fee02f.entry.js +1 -0
  158. package/dist/vega/p-6a51d720.js +1 -0
  159. package/dist/vega/{p-fe24b459.js → p-6c7b6d45.js} +1 -1
  160. package/dist/vega/{p-579cdeae.js → p-84b7a775.js} +1 -1
  161. package/dist/vega/{p-df828d90.entry.js → p-96da7d30.entry.js} +1 -1
  162. package/dist/vega/{p-88be9ec5.js → p-9d3f69cb.js} +1 -1
  163. package/dist/vega/{p-8a001caa.js → p-9f11b579.js} +1 -1
  164. package/dist/vega/{p-ba2b9663.entry.js → p-acaff62d.entry.js} +1 -1
  165. package/dist/vega/p-b63319e9.entry.js +1 -0
  166. package/dist/vega/{p-c079c935.entry.js → p-b660f38c.entry.js} +1 -1
  167. package/dist/vega/p-b8ffa42f.entry.js +1 -0
  168. package/dist/vega/{p-4fe40b76.js → p-c4564904.js} +1 -1
  169. package/dist/vega/p-d9158512.js +1 -0
  170. package/dist/vega/p-e62d41ee.js +1 -0
  171. package/dist/vega/{p-9f7154d2.js → p-ec5dee32.js} +1 -1
  172. package/dist/vega/{p-05d04c07.entry.js → p-f29d9707.entry.js} +1 -1
  173. package/dist/vega/vega.esm.js +1 -1
  174. package/package.json +3 -2
  175. package/dist/vega/p-0be4df0a.js +0 -1
  176. package/dist/vega/p-38c9d782.js +0 -1
  177. package/dist/vega/p-513bc0d9.js +0 -1
  178. package/dist/vega/p-8d4b85e7.entry.js +0 -1
  179. package/dist/vega/p-c5d3b008.entry.js +0 -1
  180. package/dist/vega/p-d25ca0c3.entry.js +0 -1
  181. package/dist/vega/p-f4da615a.js +0 -3
@@ -1,36 +1,187 @@
1
1
  import { AppendChildrenAction } from '../../actions/append-child-nodes-action';
2
2
  import { InsertChildrenAfterAction } from '../../actions/insert-children-after-block';
3
3
  import { RemoveChildrenAction } from '../../actions/remove-child-action';
4
+ import { ReplaceNestListAction } from '../../actions/replace-nest-list-action';
4
5
  import { SyncUpSelectionAction } from '../../actions/sync-up-selection-action';
5
- import { ActionHandleStrategy } from '../action-handle-strategy.abstract';
6
+ import { RTEListBlock } from '../../blocks/list-block';
7
+ import { RTEListItemBlock } from '../../blocks/list-item-block';
8
+ import { normalizeMixedListSelection } from './list-transform-selection';
9
+ import { ListAnnotationStrategy } from './list-annotation-strategy.abstract';
6
10
  /**
7
11
  * Convert the selected blocks to list strategy.
8
12
  */
9
- export class ListTransformToListStrategy extends ActionHandleStrategy {
13
+ export class ListTransformToListStrategy extends ListAnnotationStrategy {
10
14
  /**
11
15
  * @inheritDoc
12
16
  */
13
17
  handleAction(action, target) {
18
+ var _a;
14
19
  const selectedBlocks = action.selectedBlocks;
15
- const bulletList = target.parent.createList(action.listType);
16
20
  const isSameList = selectedBlocks.every((block) => block.parent === target);
21
+ const rootContent = this.getRootContent(target);
22
+ if (!rootContent) {
23
+ return;
24
+ }
25
+ // Nested list case: target.parent is RTEListItemBlock, not VegaRTEContent.
26
+ // Replace the entry in the parent item's nestList using the existing ReplaceNestListAction.
27
+ if (target.parent instanceof RTEListItemBlock) {
28
+ if (isSameList) {
29
+ const newList = this.createListFromSource(rootContent, target, action.listType);
30
+ newList.apply(new AppendChildrenAction(target.children));
31
+ const parentListItem = target.parent;
32
+ const newNestList = ((_a = parentListItem.nestList) !== null && _a !== void 0 ? _a : []).map((list) => (list === target ? newList : list));
33
+ // Adjacent same-type merge is handled automatically by ListItemReplaceNestListStrategy.
34
+ parentListItem.apply(new ReplaceNestListAction(newNestList));
35
+ selectedBlocks.forEach((block) => block.children.map((node) => node.apply(new SyncUpSelectionAction())));
36
+ }
37
+ else {
38
+ this.handleCrossListTransform(action, target);
39
+ }
40
+ return;
41
+ }
42
+ // Root list case: target.parent is VegaRTEContent.
43
+ // When all selected blocks are list items from different lists, convert each
44
+ // affected list's type in place (preserving nesting), then normalize adjacent
45
+ // same-type root lists into one.
46
+ if (!isSameList && selectedBlocks.every((block) => block instanceof RTEListItemBlock)) {
47
+ const affectedLists = new Set(selectedBlocks.map((block) => block.parent));
48
+ // Track which root lists result from conversion (new lists replace old ones).
49
+ const convertedRootLists = new Set();
50
+ affectedLists.forEach((list) => {
51
+ if (list.type !== action.listType) {
52
+ this.convertListTypeInPlace(list, action.listType);
53
+ }
54
+ });
55
+ // Collect current top-level lists that contain any selected item, grouped
56
+ // by their root or HTML-block container.
57
+ const affectedContainers = new Set();
58
+ selectedBlocks.forEach((block) => {
59
+ const parentList = block.parent;
60
+ if (!(parentList.parent instanceof RTEListItemBlock)) {
61
+ convertedRootLists.add(parentList);
62
+ affectedContainers.add(parentList.parent);
63
+ }
64
+ });
65
+ // Only merge adjacent root lists when BOTH are affected by this transform.
66
+ affectedContainers.forEach((container) => {
67
+ for (let i = 0; i < container.children.length - 1;) {
68
+ const current = container.children[i];
69
+ const next = container.children[i + 1];
70
+ if (current instanceof RTEListBlock &&
71
+ next instanceof RTEListBlock &&
72
+ current.type === next.type &&
73
+ this.haveSameListAnnotations(current, next) &&
74
+ convertedRootLists.has(current) &&
75
+ convertedRootLists.has(next)) {
76
+ current.apply(new AppendChildrenAction([...next.children]));
77
+ container.apply(new RemoveChildrenAction(next));
78
+ convertedRootLists.delete(next);
79
+ }
80
+ else {
81
+ i++;
82
+ }
83
+ }
84
+ });
85
+ selectedBlocks.forEach((block) => block.children.map((node) => node.apply(new SyncUpSelectionAction())));
86
+ return;
87
+ }
88
+ const bulletList = this.createListFromSource(rootContent, target, action.listType);
89
+ const targetContainer = target.parent;
17
90
  if (isSameList) {
18
91
  // Select one or more list items belonging to the same list, and all items in this list should be updated
19
92
  bulletList.apply(new AppendChildrenAction(target.children));
20
- target.parent.apply(new InsertChildrenAfterAction(target, bulletList));
21
- target.parent.apply(new RemoveChildrenAction(target));
93
+ targetContainer.apply(new InsertChildrenAfterAction(target, bulletList));
94
+ targetContainer.apply(new RemoveChildrenAction(target));
22
95
  selectedBlocks.forEach((block) => block.children.map((node) => node.apply(new SyncUpSelectionAction())));
23
96
  }
24
97
  else {
25
- const listItems = action.selectedBlocks.map((block) => target.parent.toListItem(block));
98
+ const mixedSelection = normalizeMixedListSelection(action.selectedBlocks, action.listType);
99
+ const listItems = mixedSelection.map((block) => rootContent.toListItem(block));
26
100
  bulletList.apply(new AppendChildrenAction(listItems));
27
- target.parent.apply(new InsertChildrenAfterAction(target, bulletList));
28
- action.selectedBlocks.forEach((block) => {
101
+ targetContainer.apply(new InsertChildrenAfterAction(target, bulletList));
102
+ mixedSelection.forEach((block) => {
29
103
  block.parent.apply(new RemoveChildrenAction(block));
30
104
  });
31
105
  if (target.children.length === 0) {
32
- target.parent.apply(new RemoveChildrenAction(target));
106
+ targetContainer.apply(new RemoveChildrenAction(target));
33
107
  }
34
108
  }
35
109
  }
110
+ /**
111
+ * Convert a single list's type in place, preserving its items and their nested
112
+ * structure. Root lists are swapped in the content children; nested lists are
113
+ * swapped inside their parent item's nestList.
114
+ *
115
+ * @param {RTEListBlock} list - The list whose type should be converted.
116
+ * @param {RTEListBlock['type']} listType - The target list type.
117
+ */
118
+ convertListTypeInPlace(list, listType) {
119
+ var _a;
120
+ const rootContent = this.getRootContent(list);
121
+ if (!rootContent) {
122
+ return;
123
+ }
124
+ const parent = list.parent;
125
+ const newList = this.createListFromSource(rootContent, list, listType);
126
+ newList.apply(new AppendChildrenAction([...list.children]));
127
+ if (parent instanceof RTEListItemBlock) {
128
+ // Adjacent same-type merge is handled automatically by ListItemReplaceNestListStrategy.
129
+ const newNestList = ((_a = parent.nestList) !== null && _a !== void 0 ? _a : []).map((entry) => entry === list ? newList : entry);
130
+ parent.apply(new ReplaceNestListAction(newNestList));
131
+ }
132
+ else {
133
+ parent.apply(new InsertChildrenAfterAction(list, newList));
134
+ parent.apply(new RemoveChildrenAction(list));
135
+ }
136
+ }
137
+ /**
138
+ * Handle the case where selected blocks span multiple nestLists under the same parent item.
139
+ * Transform each affected list and then merge adjacent same-type lists.
140
+ *
141
+ * @param {TransformListAction} action - The transform action with selection and target list type.
142
+ * @param {RTEListBlock} target - The nested list where transformation starts.
143
+ */
144
+ handleCrossListTransform(action, target) {
145
+ if (!(target.parent instanceof RTEListItemBlock)) {
146
+ return;
147
+ }
148
+ const rootContent = this.getRootContent(target);
149
+ if (!rootContent) {
150
+ return;
151
+ }
152
+ const parentListItem = target.parent;
153
+ const parentNestLists = parentListItem.nestList;
154
+ const affectedLists = new Set(action.selectedBlocks
155
+ .filter((block) => block instanceof RTEListItemBlock)
156
+ .map((block) => block.parent)
157
+ .filter((list) => parentNestLists.includes(list)));
158
+ if (!affectedLists.size) {
159
+ return;
160
+ }
161
+ const newNestList = parentNestLists.map((list) => {
162
+ if (!affectedLists.has(list)) {
163
+ return list;
164
+ }
165
+ const newList = this.createListFromSource(rootContent, list, action.listType);
166
+ newList.apply(new AppendChildrenAction(list.children));
167
+ return newList;
168
+ });
169
+ // Adjacent same-type merge is handled automatically by ListItemReplaceNestListStrategy.
170
+ parentListItem.apply(new ReplaceNestListAction(newNestList));
171
+ action.selectedBlocks.forEach((block) => block.children.map((node) => node.apply(new SyncUpSelectionAction())));
172
+ }
173
+ /**
174
+ * Create a replacement list through the owning content factory while retaining
175
+ * the source list's container annotations.
176
+ *
177
+ * @param {VegaRTEContent} rootContent - Editor content owning the factory.
178
+ * @param {RTEListBlock} source - List whose annotations should be retained.
179
+ * @param {RTEListBlock['type']} listType - Replacement list type.
180
+ * @returns {RTEListBlock} New annotated list shell.
181
+ */
182
+ createListFromSource(rootContent, source, listType) {
183
+ const list = rootContent.createList(listType);
184
+ this.copyListAnnotations(source, list);
185
+ return list;
186
+ }
36
187
  }
@@ -3,50 +3,416 @@ import { AppendChildrenAction } from '../../actions/append-child-nodes-action';
3
3
  import { InsertChildrenAfterAction } from '../../actions/insert-children-after-block';
4
4
  import { InsertChildrenBeforeAction } from '../../actions/insert-children-before-block';
5
5
  import { RemoveChildrenAction } from '../../actions/remove-child-action';
6
+ import { ReplaceNestListAction } from '../../actions/replace-nest-list-action';
6
7
  import { SyncUpSelectionAction } from '../../actions/sync-up-selection-action';
8
+ import { TransformParagraphAction } from '../../actions/transform-paragraph-action';
9
+ import { RTEHtmlBlock } from '../../blocks/html-block';
10
+ import { RTEListBlock } from '../../blocks/list-block';
11
+ import { RTEListItemBlock } from '../../blocks/list-item-block';
7
12
  import { RTETextBlock } from '../../blocks/text-block';
8
- import { ActionHandleStrategy } from '../action-handle-strategy.abstract';
13
+ import { ListAnnotationStrategy } from './list-annotation-strategy.abstract';
9
14
  /**
10
15
  * Convert the selected list block to paragraph strategy.
11
16
  */
12
- export class ListTransformToParagraphStrategy extends ActionHandleStrategy {
17
+ export class ListTransformToParagraphStrategy extends ListAnnotationStrategy {
13
18
  /**
14
19
  * @inheritDoc
15
20
  */
16
21
  handleAction(action, target) {
22
+ const selectedSegments = this.getSelectedSegments(action.selectedBlocks);
23
+ if (selectedSegments.length === 0 || !this.hasConsistentTargetAndRoot(selectedSegments, target)) {
24
+ return;
25
+ }
26
+ this.syncSelection(selectedSegments);
27
+ [...selectedSegments]
28
+ .reverse()
29
+ .forEach((segment) => this.transformSegment(segment));
30
+ }
31
+ /**
32
+ * Ensure the action is applied to the first selected item's parent list and
33
+ * every selected item belongs to the same editor content.
34
+ *
35
+ * @param {RTEListItemBlock[][]} selectedSegments - Normalized selection segments.
36
+ * @param {RTEListBlock} target - List receiving the transform action.
37
+ * @returns {boolean} Whether the target and root content are consistent.
38
+ */
39
+ hasConsistentTargetAndRoot(selectedSegments, target) {
40
+ if (selectedSegments[0][0].parent !== target) {
41
+ return false;
42
+ }
43
+ const targetRoot = this.getRootContent(target);
44
+ return Boolean(targetRoot &&
45
+ selectedSegments.every((segment) => segment.every((item) => this.getRootContent(item) === targetRoot)));
46
+ }
47
+ /**
48
+ * Capture selected text nodes in document order before reverse-order tree
49
+ * mutations move them into paragraphs.
50
+ *
51
+ * @param {RTEListItemBlock[][]} selectedSegments - Normalized selection segments.
52
+ */
53
+ syncSelection(selectedSegments) {
54
+ selectedSegments.forEach((segment) => {
55
+ segment.forEach((block) => {
56
+ block.children.forEach((node) => node.apply(new SyncUpSelectionAction()));
57
+ });
58
+ });
59
+ }
60
+ /**
61
+ * Transform one normalized segment without recursively dispatching another
62
+ * flushable action.
63
+ *
64
+ * @param {RTEListItemBlock[]} segment - Contiguous items sharing one parent list.
65
+ */
66
+ transformSegment(segment) {
67
+ const segmentTarget = segment[0].parent;
68
+ const normalizedAction = new TransformParagraphAction(segment);
69
+ if (segmentTarget.parent instanceof RTEListItemBlock) {
70
+ this.handleNestedListCase(normalizedAction, segmentTarget);
71
+ return;
72
+ }
73
+ this.handleRootListCase(normalizedAction, segmentTarget);
74
+ }
75
+ /**
76
+ * Handle the case where the target list is at root level (parent is VegaRTEContent).
77
+ *
78
+ * @param {TransformParagraphAction} action - The paragraph transform action.
79
+ * @param {RTEListBlock} target - The root list being transformed.
80
+ */
81
+ handleRootListCase(action, target) {
82
+ // handleAction validates that the target belongs to an editor content root.
83
+ const rootContent = this.getRootContent(target);
17
84
  let isSelectedFirstBlock = false;
18
85
  let isSelectedLastBlock = false;
19
86
  const selectedBlocks = action.selectedBlocks;
20
- const currentParagraph = selectedBlocks.map((block) => {
21
- block.children.map((node) => node.apply(new SyncUpSelectionAction()));
87
+ // Build an operation-local insertion sequence. Paragraphs are merge
88
+ // boundaries; only consecutive same-type promoted lists are merged.
89
+ const insertionBlocks = [];
90
+ selectedBlocks.forEach((block) => {
91
+ var _a;
22
92
  if (block === target.children[0])
23
93
  isSelectedFirstBlock = true;
24
94
  if (block === target.children[target.children.length - 1])
25
95
  isSelectedLastBlock = true;
26
- return this.toParagraph(block);
96
+ insertionBlocks.push(this.toParagraph(block));
97
+ for (const nestList of (_a = block.nestList) !== null && _a !== void 0 ? _a : []) {
98
+ this.appendListBlock(insertionBlocks, nestList);
99
+ }
27
100
  });
28
101
  if (isSelectedFirstBlock) {
29
- target.parent.apply(new InsertChildrenBeforeAction(target, ...currentParagraph));
102
+ target.parent.apply(new InsertChildrenBeforeAction(target, ...insertionBlocks));
30
103
  }
31
104
  else if (isSelectedLastBlock) {
32
- target.parent.apply(new InsertChildrenAfterAction(target, ...currentParagraph));
105
+ target.parent.apply(new InsertChildrenAfterAction(target, ...insertionBlocks));
33
106
  }
34
107
  else {
35
108
  const startIndex = target.children.indexOf(selectedBlocks[0]);
36
109
  const lastIndex = target.children.indexOf(selectedBlocks[selectedBlocks.length - 1]);
37
- const firstBulletList = target.parent.createList(target.type);
110
+ const firstBulletList = this.createListFromSource(rootContent, target);
38
111
  firstBulletList.apply(new AppendChildrenAction(target.children.slice(0, startIndex)));
39
- const lastBulletList = target.parent.createList(target.type);
112
+ const lastBulletList = this.createListFromSource(rootContent, target);
40
113
  lastBulletList.apply(new AppendChildrenAction(target.children.slice(lastIndex + 1)));
41
- target.parent.apply(new InsertChildrenBeforeAction(target, firstBulletList, ...currentParagraph, lastBulletList));
114
+ // Merge last insertionBlock with lastBulletList if same type
115
+ const lastInsertion = insertionBlocks[insertionBlocks.length - 1];
116
+ if (lastInsertion instanceof RTEListBlock &&
117
+ lastBulletList.children.length > 0 &&
118
+ lastInsertion.type === lastBulletList.type &&
119
+ this.haveSameListAnnotations(lastInsertion, lastBulletList)) {
120
+ lastInsertion.apply(new AppendChildrenAction(lastBulletList.children));
121
+ target.parent.apply(new InsertChildrenBeforeAction(target, firstBulletList, ...insertionBlocks));
122
+ }
123
+ else {
124
+ target.parent.apply(new InsertChildrenBeforeAction(target, firstBulletList, ...insertionBlocks, lastBulletList));
125
+ }
42
126
  target.parent.apply(new RemoveChildrenAction(target));
43
127
  }
44
128
  selectedBlocks.map((block) => {
129
+ // Clear nestList before removal to prevent ListRemoveListItemStrategy
130
+ // from promoting the same nested lists a second time.
131
+ block.nestList = [];
45
132
  target.apply(new RemoveChildrenAction(block));
46
133
  });
47
134
  if (target.children.length === 0) {
48
135
  target.parent.apply(new RemoveChildrenAction(target));
49
136
  }
137
+ else if (isSelectedFirstBlock) {
138
+ // When removing the first item(s), a promoted same-type nestList (last
139
+ // insertionBlock) ends up immediately before the remaining target. Merge
140
+ // them so the user doesn't see two adjacent same-type lists.
141
+ const lastInserted = insertionBlocks[insertionBlocks.length - 1];
142
+ if (lastInserted instanceof RTEListBlock &&
143
+ lastInserted.type === target.type &&
144
+ this.haveSameListAnnotations(lastInserted, target)) {
145
+ lastInserted.apply(new AppendChildrenAction([...target.children]));
146
+ target.parent.apply(new RemoveChildrenAction(target));
147
+ }
148
+ }
149
+ }
150
+ /**
151
+ * Handle the case where the target list is nested (parent is RTEListItemBlock).
152
+ *
153
+ * Algorithm:
154
+ * 1. Build the ancestor path from root list down to the target nested list.
155
+ * 2. At each level on the path, collect "trailing" items (items after the ancestor).
156
+ * 3. Trim each list along the path to keep only the "before" portion.
157
+ * 4. Collect trailing items from all levels + selected item's own nestList children.
158
+ * 5. Group trailing items into lists by consecutive type.
159
+ * 6. Insert into content: [before-root-list, paragraphs, ...after-lists].
160
+ *
161
+ * @param {TransformParagraphAction} action - The paragraph transform action.
162
+ * @param {RTEListBlock} target - The nested list being transformed.
163
+ */
164
+ handleNestedListCase(action, target) {
165
+ const selectedBlocks = action.selectedBlocks;
166
+ const rootContent = this.getRootContent(target);
167
+ const selectedItem = selectedBlocks[0];
168
+ const selectedIndex = target.children.indexOf(selectedItem);
169
+ // Emit each selected item as paragraph + its own nested lists so that
170
+ // selecting multiple levels never moves a child list past another paragraph.
171
+ const insertions = [];
172
+ selectedBlocks.forEach((block) => {
173
+ var _a;
174
+ insertions.push(this.toParagraph(block));
175
+ for (const nestList of (_a = block.nestList) !== null && _a !== void 0 ? _a : []) {
176
+ this.appendListBlock(insertions, nestList);
177
+ }
178
+ });
179
+ const lastSelectedIndex = target.children.indexOf(selectedBlocks[selectedBlocks.length - 1]);
180
+ // Collect trailing items from the nested list (items AFTER the last selected)
181
+ const nestedTrailingItems = target.children.slice(lastSelectedIndex + 1);
182
+ const ancestorPath = [];
183
+ let currentList = target;
184
+ while (currentList.parent instanceof RTEListItemBlock) {
185
+ const parentItem = currentList.parent;
186
+ const grandParentList = parentItem.parent;
187
+ const ancestorIndex = grandParentList.children.indexOf(parentItem);
188
+ // Collect nestLists of parentItem that are AFTER currentList
189
+ const parentNestLists = parentItem.nestList;
190
+ const nestListIndex = parentNestLists.indexOf(currentList);
191
+ const trailingNestLists = parentNestLists.slice(nestListIndex + 1);
192
+ ancestorPath.push({ list: grandParentList, ancestorIndex, trailingNestLists });
193
+ currentList = grandParentList;
194
+ }
195
+ // currentList is now the root-level list
196
+ const rootList = currentList;
197
+ const rootContainer = rootList.parent;
198
+ const trailingGroups = [];
199
+ // 1. Trailing items from the target nested list (same type as target)
200
+ if (nestedTrailingItems.length > 0) {
201
+ trailingGroups.push({ items: nestedTrailingItems, sourceList: target });
202
+ }
203
+ // 2. Trailing nestLists from ancestors (innermost to outermost)
204
+ // 3. Trailing items from each ancestor level's list
205
+ for (const level of ancestorPath) {
206
+ // Trailing nestLists from the ancestor item
207
+ for (const trailingNest of level.trailingNestLists) {
208
+ if (trailingNest.children.length > 0) {
209
+ trailingGroups.push({ items: [...trailingNest.children], sourceList: trailingNest });
210
+ }
211
+ }
212
+ // Trailing items from ancestor's list (items after the ancestor item)
213
+ const trailingFromLevel = level.list.children.slice(level.ancestorIndex + 1);
214
+ if (trailingFromLevel.length > 0) {
215
+ trailingGroups.push({ items: trailingFromLevel, sourceList: level.list });
216
+ }
217
+ }
218
+ // Merge only groups whose list type and container annotations match. Different
219
+ // class/style/attribute boundaries must survive the structural reconstruction.
220
+ const mergedGroups = [];
221
+ for (const group of trailingGroups) {
222
+ const prev = mergedGroups[mergedGroups.length - 1];
223
+ if (prev &&
224
+ prev.sourceList.type === group.sourceList.type &&
225
+ this.haveSameListAnnotations(prev.sourceList, group.sourceList)) {
226
+ prev.items.push(...group.items);
227
+ }
228
+ else {
229
+ mergedGroups.push({ items: [...group.items], sourceList: group.sourceList });
230
+ }
231
+ }
232
+ // Build the "after" lists
233
+ const afterLists = mergedGroups.map((group) => {
234
+ const newList = this.createListFromSource(rootContent, group.sourceList);
235
+ newList.apply(new AppendChildrenAction(group.items));
236
+ return newList;
237
+ });
238
+ afterLists.forEach((list) => this.appendListBlock(insertions, list));
239
+ // --- Now trim the "before" portion ---
240
+ // Trim target nested list: keep only items before selected
241
+ target.children = target.children.slice(0, selectedIndex);
242
+ // Clean up the target nested list's parent item's nestList
243
+ const targetParentItem = target.parent;
244
+ const targetParentNestLists = targetParentItem.nestList;
245
+ const targetNestIndex = targetParentNestLists.indexOf(target);
246
+ // Keep only nestLists up to and including the target (remove trailing ones we already collected)
247
+ let trimmedNestList = targetParentNestLists.slice(0, targetNestIndex + 1);
248
+ // If target is now empty, remove it too
249
+ if (target.children.length === 0) {
250
+ trimmedNestList = trimmedNestList.filter((l) => l !== target);
251
+ }
252
+ targetParentItem.apply(new ReplaceNestListAction(trimmedNestList));
253
+ // Trim ancestor levels: remove trailing items and trailing nestLists
254
+ for (const level of ancestorPath) {
255
+ // Remove trailing items from the ancestor's list
256
+ level.list.children = level.list.children.slice(0, level.ancestorIndex + 1);
257
+ // Remove trailing nestLists from the ancestor item
258
+ if (level.trailingNestLists.length > 0) {
259
+ const ancestorItem = level.list.children[level.ancestorIndex];
260
+ const ancestorNestLists = ancestorItem.nestList;
261
+ const firstTrailingNestIndex = ancestorNestLists.indexOf(level.trailingNestLists[0]);
262
+ if (firstTrailingNestIndex >= 0) {
263
+ const keptNestLists = ancestorNestLists.slice(0, firstTrailingNestIndex);
264
+ ancestorItem.apply(new ReplaceNestListAction(keptNestLists));
265
+ }
266
+ }
267
+ }
268
+ rootContainer.apply(new InsertChildrenAfterAction(rootList, ...insertions));
269
+ }
270
+ /**
271
+ * Normalize selected items into document order and split them into contiguous
272
+ * segments that share the same immediate parent list. Unlike Shift+Tab, the
273
+ * toolbar action keeps selected descendants so every selected item becomes a
274
+ * paragraph.
275
+ *
276
+ * @param {RTEBlock[]} selectedBlocks - Raw selected blocks.
277
+ * @returns {RTEListItemBlock[][]} Parent-based contiguous selection segments.
278
+ */
279
+ getSelectedSegments(selectedBlocks) {
280
+ const selectedItems = Array.from(new Set(selectedBlocks.filter((block) => block instanceof RTEListItemBlock)))
281
+ .map((item) => ({ item, path: this.getStructuralPath(item) }))
282
+ .filter((entry) => entry.path !== null)
283
+ .sort((a, b) => this.compareStructuralPaths(a.path, b.path))
284
+ .map((entry) => entry.item);
285
+ const segments = [];
286
+ for (const item of selectedItems) {
287
+ const segment = segments[segments.length - 1];
288
+ const previousItem = segment === null || segment === void 0 ? void 0 : segment[segment.length - 1];
289
+ const isContiguousSibling = (previousItem === null || previousItem === void 0 ? void 0 : previousItem.parent) === item.parent &&
290
+ item.parent.children.indexOf(item) - item.parent.children.indexOf(previousItem) === 1;
291
+ if (isContiguousSibling) {
292
+ segment.push(item);
293
+ }
294
+ else {
295
+ segments.push([item]);
296
+ }
297
+ }
298
+ return segments;
299
+ }
300
+ /**
301
+ * Resolve a list item's structural document path, including the positions of
302
+ * root lists, owning list items, nested lists, and the item itself.
303
+ *
304
+ * @param {RTEListItemBlock} item - Selected list item.
305
+ * @returns {number[] | null} Structural path, or null for a detached item.
306
+ */
307
+ getStructuralPath(item) {
308
+ var _a;
309
+ const path = [];
310
+ const visitedLists = new Set();
311
+ let currentItem = item;
312
+ let currentList = item.parent;
313
+ while (!visitedLists.has(currentList)) {
314
+ visitedLists.add(currentList);
315
+ const itemIndex = currentList.children.indexOf(currentItem);
316
+ if (itemIndex < 0) {
317
+ return null;
318
+ }
319
+ path.unshift(itemIndex);
320
+ if (currentList.parent.dtoName === 'VegaRTEContent' ||
321
+ currentList.parent.dtoName === 'RTEHtmlBlock') {
322
+ const containerPath = this.getContainerPath(currentList);
323
+ return containerPath ? [...containerPath, ...path] : null;
324
+ }
325
+ if (!(currentList.parent instanceof RTEListItemBlock)) {
326
+ return null;
327
+ }
328
+ const ownerItem = currentList.parent;
329
+ const nestListIndex = ((_a = ownerItem.nestList) !== null && _a !== void 0 ? _a : []).indexOf(currentList);
330
+ if (nestListIndex < 0) {
331
+ return null;
332
+ }
333
+ path.unshift(nestListIndex);
334
+ currentItem = ownerItem;
335
+ currentList = ownerItem.parent;
336
+ }
337
+ return null;
338
+ }
339
+ /**
340
+ * Resolve a root list's path through zero or more HTML containers to the
341
+ * editor content.
342
+ *
343
+ * @param {RTEListBlock} rootList - List whose parent is a content container.
344
+ * @returns {number[] | null} Container path, or null for detached/cyclic ownership.
345
+ */
346
+ getContainerPath(rootList) {
347
+ const path = [];
348
+ const visitedContainers = new Set();
349
+ let child = rootList;
350
+ let container = rootList.parent;
351
+ while (container instanceof RTEHtmlBlock) {
352
+ if (visitedContainers.has(container)) {
353
+ return null;
354
+ }
355
+ visitedContainers.add(container);
356
+ const childIndex = container.children.indexOf(child);
357
+ if (childIndex < 0) {
358
+ return null;
359
+ }
360
+ path.unshift(childIndex);
361
+ child = container;
362
+ container = container.parent;
363
+ }
364
+ const rootChildIndex = container.children.indexOf(child);
365
+ if (rootChildIndex < 0) {
366
+ return null;
367
+ }
368
+ path.unshift(rootChildIndex);
369
+ return path;
370
+ }
371
+ /**
372
+ * Compare two structural paths in document order.
373
+ *
374
+ * @param {number[]} firstPath - First structural path.
375
+ * @param {number[]} secondPath - Second structural path.
376
+ * @returns {number} Relative document order.
377
+ */
378
+ compareStructuralPaths(firstPath, secondPath) {
379
+ const length = Math.min(firstPath.length, secondPath.length);
380
+ for (let index = 0; index < length; index++) {
381
+ if (firstPath[index] !== secondPath[index]) {
382
+ return firstPath[index] - secondPath[index];
383
+ }
384
+ }
385
+ return firstPath.length - secondPath.length;
386
+ }
387
+ /**
388
+ * Append a list to an operation-local block sequence, merging only with the
389
+ * immediately preceding same-type list in that sequence.
390
+ *
391
+ * @param {RTEBlock[]} blocks - Operation-local output sequence.
392
+ * @param {RTEListBlock} list - List to append or merge.
393
+ */
394
+ appendListBlock(blocks, list) {
395
+ const previousBlock = blocks[blocks.length - 1];
396
+ if (previousBlock instanceof RTEListBlock &&
397
+ previousBlock.type === list.type &&
398
+ this.haveSameListAnnotations(previousBlock, list)) {
399
+ previousBlock.apply(new AppendChildrenAction([...list.children]));
400
+ return;
401
+ }
402
+ blocks.push(list);
403
+ }
404
+ /**
405
+ * Create a list through the content factory and retain the source list's
406
+ * container annotations when a structural split requires a new list block.
407
+ *
408
+ * @param {VegaRTEContent} rootContent - Editor content that owns the factory.
409
+ * @param {RTEListBlock} source - List whose type and annotations should be retained.
410
+ * @returns {RTEListBlock} Newly created list shell.
411
+ */
412
+ createListFromSource(rootContent, source) {
413
+ const list = rootContent.createList(source.type);
414
+ this.copyListAnnotations(source, list);
415
+ return list;
50
416
  }
51
417
  /**
52
418
  * Converts a RTEListItemBlock to a RTETextBlock representing a paragraph.