@globalpayments/vega 2.61.0 → 2.63.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 (444) hide show
  1. package/dist/cjs/{app-globals-7e624dd0.js → app-globals-8f5fa42a.js} +23 -15
  2. package/dist/cjs/base-renderer-0a3b62b7.js +9 -0
  3. package/dist/cjs/{child-nodes-event-prevent-slimmer-184fe3b2.js → child-nodes-event-prevent-slimmer-4e96270e.js} +1 -1
  4. package/dist/cjs/{code-block-ecb2df41.js → code-block-eb66d852.js} +73 -22
  5. package/dist/cjs/{component-value-history-controller-slimmer.abstract-58a0f64c.js → component-value-history-controller-slimmer.abstract-62cdf04c.js} +16 -182
  6. package/dist/cjs/{design-token-16f74439.js → design-token-76bb47bd.js} +1 -1
  7. package/dist/cjs/{dom-node-subject-factory-4eb1fec2.js → dom-node-subject-observer-factory-58e3c010.js} +41 -0
  8. package/dist/cjs/{content-state-d7b8e70b.js → dto-renderer-manager-f3894490.js} +1647 -1501
  9. package/dist/cjs/{element-appender-slimmer-c4816142.js → element-appender-slimmer-e8dac628.js} +7 -8
  10. package/dist/cjs/{event-emit-slimmer-2da7c9d6.js → event-emit-slimmer-428d8802.js} +3 -4
  11. package/dist/cjs/{form-field-controller-slimmer-dab30e5c.js → form-field-controller-slimmer-cc6e53a4.js} +4 -5
  12. package/dist/cjs/{image-annotation-action-7eaab3ce.js → image-annotation-action-a628ec9b.js} +24 -81
  13. package/dist/cjs/{index-da628bba.js → index-5505e8dd.js} +3 -3
  14. package/dist/cjs/index.cjs.js +49 -23
  15. package/dist/cjs/{icon-manager-9072356d.js → internal-icon-manager-32f9ed63.js} +51 -0
  16. package/dist/cjs/{internal-vega-event-manager-7b87c2f4.js → internal-vega-event-manager-28b957c8.js} +73 -73
  17. package/dist/cjs/language-extension-20a1dba5.js +207 -0
  18. package/dist/cjs/loader.cjs.js +14 -12
  19. package/dist/cjs/{min-number-rule-965fc43d.js → min-number-rule-dc555309.js} +14 -8
  20. package/dist/cjs/{public-rules-21622bd0.js → public-rules-5d0f3a5f.js} +5 -5
  21. package/dist/cjs/range-cfc45f9e.js +178 -0
  22. package/dist/cjs/{responsive-format-facade-0d22ff78.js → responsive-format-facade-7e933525.js} +4 -3
  23. package/dist/cjs/{rich-text-editor-required-rule-8d7e441a.js → rich-text-editor-required-rule-72170c10.js} +2 -2
  24. package/dist/cjs/{string-input-formatter-slimmer-5a744e71.js → string-input-formatter-slimmer-f6c7a255.js} +4 -4
  25. package/dist/cjs/{style-formatter-a66813a2.js → style-formatter-702df81e.js} +1 -1
  26. package/dist/cjs/{sub-state-notify-slimmer-9602b5bb.js → sub-state-notify-slimmer-bb64fcfc.js} +4 -4
  27. package/dist/cjs/{sub-state-observer-slimmer-df7df5bb.js → sub-state-observer-slimmer-84175d61.js} +4 -4
  28. package/dist/cjs/{vega-skeleton-loader-controller-9c54f3aa.js → token-extension-23ccff1d.js} +679 -3
  29. package/dist/cjs/vega-accordion.cjs.entry.js +15 -16
  30. package/dist/cjs/vega-app-header-button.cjs.entry.js +20 -21
  31. package/dist/cjs/vega-banner.cjs.entry.js +7 -9
  32. package/dist/cjs/vega-box.cjs.entry.js +13 -12
  33. package/dist/cjs/vega-brand-logo.cjs.entry.js +1 -2
  34. package/dist/cjs/vega-breadcrumb.cjs.entry.js +44 -78
  35. package/dist/cjs/vega-button-circle.cjs.entry.js +16 -16
  36. package/dist/cjs/vega-button-group_2.cjs.entry.js +11 -12
  37. package/dist/cjs/vega-button-link.cjs.entry.js +22 -21
  38. package/dist/cjs/vega-button.cjs.entry.js +15 -15
  39. package/dist/cjs/vega-calendar_4.cjs.entry.js +22 -24
  40. package/dist/cjs/vega-card.cjs.entry.js +12 -11
  41. package/dist/cjs/vega-carousel.cjs.entry.js +13 -13
  42. package/dist/cjs/vega-checkbox_2.cjs.entry.js +12 -13
  43. package/dist/cjs/vega-chip.cjs.entry.js +17 -17
  44. package/dist/cjs/vega-code-block.cjs.entry.js +16 -17
  45. package/dist/cjs/vega-color-picker.cjs.entry.js +6 -7
  46. package/dist/cjs/vega-combo-box.cjs.entry.js +14 -15
  47. package/dist/cjs/vega-date-picker_2.cjs.entry.js +30 -31
  48. package/dist/cjs/vega-dialog_2.cjs.entry.js +27 -27
  49. package/dist/cjs/vega-divider.cjs.entry.js +12 -11
  50. package/dist/cjs/vega-dropdown_5.cjs.entry.js +32 -32
  51. package/dist/cjs/vega-env-manager-23b8b23c.js +2 -2
  52. package/dist/cjs/vega-field-label.cjs.entry.js +6 -7
  53. package/dist/cjs/vega-file-uploader.cjs.entry.js +15 -17
  54. package/dist/cjs/vega-flag-icon.cjs.entry.js +13 -13
  55. package/dist/cjs/vega-flex.cjs.entry.js +12 -11
  56. package/dist/cjs/vega-font.cjs.entry.js +12 -11
  57. package/dist/cjs/vega-form.cjs.entry.js +13 -14
  58. package/dist/cjs/vega-grid.cjs.entry.js +12 -11
  59. package/dist/cjs/vega-icon.cjs.entry.js +15 -14
  60. package/dist/cjs/vega-image-uploader.cjs.entry.js +18 -18
  61. package/dist/cjs/vega-input-credit-card.cjs.entry.js +14 -16
  62. package/dist/cjs/vega-input-numeric.cjs.entry.js +57 -12
  63. package/dist/cjs/vega-input-phone-number.cjs.entry.js +20 -21
  64. package/dist/cjs/vega-input-range.cjs.entry.js +11 -12
  65. package/dist/cjs/vega-input-select.cjs.entry.js +27 -28
  66. package/dist/cjs/vega-input.cjs.entry.js +13 -14
  67. package/dist/cjs/vega-item-toggle.cjs.entry.js +5 -6
  68. package/dist/cjs/vega-left-nav_5.cjs.entry.js +33 -34
  69. package/dist/cjs/vega-loader-wrapper_2.cjs.entry.js +13 -12
  70. package/dist/cjs/vega-page-notification_2.cjs.entry.js +2 -3
  71. package/dist/cjs/vega-pagination-page-selector-mobile.cjs.entry.js +8 -9
  72. package/dist/cjs/vega-pagination-page-size-selector-mobile.cjs.entry.js +3 -4
  73. package/dist/cjs/vega-pagination.cjs.entry.js +18 -18
  74. package/dist/cjs/vega-popover_2.cjs.entry.js +18 -18
  75. package/dist/cjs/vega-progress-tracker.cjs.entry.js +5 -6
  76. package/dist/cjs/vega-radio_2.cjs.entry.js +13 -14
  77. package/dist/cjs/vega-rich-text-content.cjs.entry.js +53 -48
  78. package/dist/cjs/vega-rich-text-editor_4.cjs.entry.js +387 -261
  79. package/dist/cjs/vega-segment-control.cjs.entry.js +5 -6
  80. package/dist/cjs/vega-selection-chip_2.cjs.entry.js +20 -20
  81. package/dist/cjs/vega-selection-tile_2.cjs.entry.js +13 -14
  82. package/dist/cjs/vega-sidenav_3.cjs.entry.js +24 -25
  83. package/dist/cjs/vega-signature-capture.cjs.entry.js +16 -17
  84. package/dist/cjs/vega-stepper.cjs.entry.js +13 -14
  85. package/dist/cjs/vega-tab-group_2.cjs.entry.js +8 -9
  86. package/dist/cjs/vega-table_8.cjs.entry.js +58 -59
  87. package/dist/cjs/vega-textarea.cjs.entry.js +16 -11
  88. package/dist/cjs/vega-time-picker_2.cjs.entry.js +32 -24
  89. package/dist/cjs/vega-toggle-switch.cjs.entry.js +7 -8
  90. package/dist/cjs/vega-tooltip_2.cjs.entry.js +12 -12
  91. package/dist/cjs/vega.cjs.js +14 -12
  92. package/dist/collection/components/vega-breadcrumb/slimmers/renderers/vega-breadcrumb-collapsed-item-renderer.js +4 -13
  93. package/dist/collection/components/vega-breadcrumb/slimmers/renderers/vega-breadcrumb-item-renderer.js +19 -5
  94. package/dist/collection/components/vega-breadcrumb/vega-breadcrumb.js +6 -5
  95. package/dist/collection/components/vega-button-link/vega-button-link.js +18 -19
  96. package/dist/collection/components/vega-input-numeric/slimmers/renderers/vega-input-numeric-renderer.js +27 -1
  97. package/dist/collection/components/vega-input-numeric/vega-input-numeric.js +64 -0
  98. package/dist/collection/components/vega-rich-text-content/vega-rich-text-content.js +31 -0
  99. package/dist/collection/components/vega-rich-text-editor/constants/constant.js +10 -0
  100. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/action-handle-strategy-registry.js +11 -0
  101. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/apply-annotation-strategies/node-split-text-strategy.js +6 -3
  102. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-delete-text-or-decorator-node-strategy.js +12 -6
  103. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/code-block-remove-self-strategy.js +2 -2
  104. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/insert-node-to-nearest-root-strategy.js +57 -0
  105. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/update-cursor-position-strategy.js +2 -1
  106. package/dist/collection/components/vega-rich-text-editor/dto/actions/insert-node-to-nearest-root-action.js +14 -0
  107. package/dist/collection/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.js +1 -0
  108. package/dist/collection/components/vega-rich-text-editor/dto/actions/update-cursor-position-action.js +5 -2
  109. package/dist/collection/components/vega-rich-text-editor/dto/content-state.js +12 -0
  110. package/dist/collection/components/vega-rich-text-editor/dto/nodes/text-node.js +36 -10
  111. package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/link-wrapper-renderer.js +10 -4
  112. package/dist/collection/components/vega-rich-text-editor/extensions/base-toolbar-button-renderer.js +145 -0
  113. package/dist/collection/components/vega-rich-text-editor/extensions/extension.abstract.js +97 -0
  114. package/dist/collection/components/vega-rich-text-editor/extensions/languages/language-extension.js +113 -0
  115. package/dist/collection/components/vega-rich-text-editor/extensions/languages/language-toolbar-button-renderer.js +90 -0
  116. package/dist/collection/components/vega-rich-text-editor/extensions/tokens/insert-token-node-action.js +16 -0
  117. package/dist/collection/components/vega-rich-text-editor/extensions/tokens/insert-token-node-strategy.js +20 -0
  118. package/dist/collection/components/vega-rich-text-editor/extensions/tokens/span-to-token-node-strategy.js +60 -0
  119. package/dist/collection/components/vega-rich-text-editor/extensions/tokens/token-extension.js +38 -0
  120. package/dist/collection/components/vega-rich-text-editor/extensions/tokens/token-node-renderer.js +67 -0
  121. package/dist/collection/components/vega-rich-text-editor/extensions/tokens/token-node.js +55 -0
  122. package/dist/collection/components/vega-rich-text-editor/extensions/tokens/token-toolbar-button-renderer.js +88 -0
  123. package/dist/collection/components/vega-rich-text-editor/public-api.js +38 -0
  124. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/extension-controller.js +97 -0
  125. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/focus-controller.js +8 -6
  126. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/element-to-dto-strategy/element-to-dto-strategy.abstract.js +12 -0
  127. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/selection-controller.js +9 -3
  128. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/toolbar-renderer.js +43 -18
  129. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/link-toolbar-button-slimmer.js +3 -1
  130. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/toolbar-button-slimmer.abstract.js +6 -6
  131. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/visual-mode-toolbar-button-slimmer.abstract.js +9 -9
  132. package/dist/collection/components/vega-rich-text-editor/test/dto/content-state.test.js +41 -0
  133. package/dist/collection/components/vega-rich-text-editor/vega-rich-text-editor.js +44 -11
  134. package/dist/collection/components/vega-textarea/vega-textarea.js +28 -1
  135. package/dist/collection/components/vega-time-picker/vega-time-picker.js +10 -2
  136. package/dist/collection/global/scripts/before-vega-load.js +9 -0
  137. package/dist/collection/helpers/code-format/test/code-formatter.test.js +1 -1
  138. package/dist/collection/helpers/public-api.js +1 -1
  139. package/dist/collection/helpers/rte-manager/dto-action-strategy-manager.js +2 -0
  140. package/dist/collection/helpers/validator/rules/max-number-rule.js +7 -4
  141. package/dist/collection/helpers/validator/rules/min-number-rule.js +7 -4
  142. package/dist/esm/{app-globals-ce54f0ac.js → app-globals-aaff0b25.js} +13 -5
  143. package/dist/esm/base-renderer-101f6d04.js +7 -0
  144. package/dist/esm/{child-nodes-event-prevent-slimmer-2a3115ae.js → child-nodes-event-prevent-slimmer-7fe3dc57.js} +1 -1
  145. package/dist/esm/{code-block-89a4dd13.js → code-block-68300b47.js} +67 -17
  146. package/dist/esm/{component-value-history-controller-slimmer.abstract-95b199df.js → component-value-history-controller-slimmer.abstract-ac2f1bfd.js} +13 -179
  147. package/dist/esm/{design-token-eaa7c221.js → design-token-1a36307e.js} +1 -1
  148. package/dist/esm/{dom-node-subject-factory-3c2e13f1.js → dom-node-subject-observer-factory-c7bc3035.js} +41 -1
  149. package/dist/esm/{content-state-fc47457c.js → dto-renderer-manager-af66bbd9.js} +1643 -1502
  150. package/dist/esm/{element-appender-slimmer-ce83db8a.js → element-appender-slimmer-fe68ec2d.js} +3 -4
  151. package/dist/esm/{event-emit-slimmer-4428ce26.js → event-emit-slimmer-3922d816.js} +2 -3
  152. package/dist/esm/{form-field-controller-slimmer-6e69ca4e.js → form-field-controller-slimmer-f7e8845b.js} +2 -3
  153. package/dist/esm/{image-annotation-action-53812eb7.js → image-annotation-action-f61c2693.js} +20 -76
  154. package/dist/esm/{index-1d479c88.js → index-7fe93427.js} +1 -1
  155. package/dist/esm/index.js +13 -10
  156. package/dist/esm/{icon-manager-2ee1c619.js → internal-icon-manager-f0486245.js} +51 -1
  157. package/dist/esm/{internal-vega-event-manager-a654cf8a.js → internal-vega-event-manager-cb06e987.js} +1 -1
  158. package/dist/esm/language-extension-1ada2a9d.js +204 -0
  159. package/dist/esm/loader.js +14 -12
  160. package/dist/esm/{min-number-rule-86421853.js → min-number-rule-2f1cfbf9.js} +14 -8
  161. package/dist/esm/{public-rules-095284f6.js → public-rules-9f62069a.js} +5 -5
  162. package/dist/esm/range-c2eeb794.js +176 -0
  163. package/dist/esm/{responsive-format-facade-86b6de3b.js → responsive-format-facade-5711c77d.js} +4 -3
  164. package/dist/esm/{rich-text-editor-required-rule-4e8d2db8.js → rich-text-editor-required-rule-de738309.js} +1 -1
  165. package/dist/esm/{string-input-formatter-slimmer-60897659.js → string-input-formatter-slimmer-69117deb.js} +2 -2
  166. package/dist/esm/{style-formatter-a0719a8f.js → style-formatter-2479dc61.js} +1 -1
  167. package/dist/esm/{sub-state-notify-slimmer-ee730968.js → sub-state-notify-slimmer-4252a90e.js} +1 -1
  168. package/dist/esm/{sub-state-observer-slimmer-d474634d.js → sub-state-observer-slimmer-baa8853a.js} +1 -1
  169. package/dist/esm/{vega-skeleton-loader-controller-394a6026.js → token-extension-6fc5e1f5.js} +672 -4
  170. package/dist/esm/vega-accordion.entry.js +13 -14
  171. package/dist/esm/vega-app-header-button.entry.js +14 -15
  172. package/dist/esm/vega-banner.entry.js +4 -6
  173. package/dist/esm/vega-box.entry.js +13 -12
  174. package/dist/esm/vega-brand-logo.entry.js +1 -2
  175. package/dist/esm/vega-breadcrumb.entry.js +42 -76
  176. package/dist/esm/vega-button-circle.entry.js +14 -14
  177. package/dist/esm/vega-button-group_2.entry.js +6 -7
  178. package/dist/esm/vega-button-link.entry.js +20 -19
  179. package/dist/esm/vega-button.entry.js +13 -13
  180. package/dist/esm/vega-calendar_4.entry.js +7 -9
  181. package/dist/esm/vega-card.entry.js +12 -11
  182. package/dist/esm/vega-carousel.entry.js +12 -12
  183. package/dist/esm/vega-checkbox_2.entry.js +6 -7
  184. package/dist/esm/vega-chip.entry.js +14 -14
  185. package/dist/esm/vega-code-block.entry.js +8 -9
  186. package/dist/esm/vega-color-picker.entry.js +5 -6
  187. package/dist/esm/vega-combo-box.entry.js +6 -7
  188. package/dist/esm/vega-date-picker_2.entry.js +16 -17
  189. package/dist/esm/vega-dialog_2.entry.js +15 -15
  190. package/dist/esm/vega-divider.entry.js +12 -11
  191. package/dist/esm/vega-dropdown_5.entry.js +15 -15
  192. package/dist/esm/vega-env-manager-8f8dc473.js +2 -2
  193. package/dist/esm/vega-field-label.entry.js +4 -5
  194. package/dist/esm/vega-file-uploader.entry.js +6 -8
  195. package/dist/esm/vega-flag-icon.entry.js +12 -12
  196. package/dist/esm/vega-flex.entry.js +12 -11
  197. package/dist/esm/vega-font.entry.js +12 -11
  198. package/dist/esm/vega-form.entry.js +7 -8
  199. package/dist/esm/vega-grid.entry.js +12 -11
  200. package/dist/esm/vega-icon.entry.js +12 -11
  201. package/dist/esm/vega-image-uploader.entry.js +12 -12
  202. package/dist/esm/vega-input-credit-card.entry.js +7 -9
  203. package/dist/esm/vega-input-numeric.entry.js +54 -9
  204. package/dist/esm/vega-input-phone-number.entry.js +12 -13
  205. package/dist/esm/vega-input-range.entry.js +7 -8
  206. package/dist/esm/vega-input-select.entry.js +14 -15
  207. package/dist/esm/vega-input.entry.js +8 -9
  208. package/dist/esm/vega-item-toggle.entry.js +3 -4
  209. package/dist/esm/vega-left-nav_5.entry.js +14 -15
  210. package/dist/esm/vega-loader-wrapper_2.entry.js +11 -10
  211. package/dist/esm/vega-page-notification_2.entry.js +1 -2
  212. package/dist/esm/vega-pagination-page-selector-mobile.entry.js +3 -4
  213. package/dist/esm/vega-pagination-page-size-selector-mobile.entry.js +1 -2
  214. package/dist/esm/vega-pagination.entry.js +10 -10
  215. package/dist/esm/vega-popover_2.entry.js +14 -14
  216. package/dist/esm/vega-progress-tracker.entry.js +3 -4
  217. package/dist/esm/vega-radio_2.entry.js +6 -7
  218. package/dist/esm/vega-rich-text-content.entry.js +24 -19
  219. package/dist/esm/vega-rich-text-editor_4.entry.js +342 -216
  220. package/dist/esm/vega-segment-control.entry.js +4 -5
  221. package/dist/esm/vega-selection-chip_2.entry.js +15 -15
  222. package/dist/esm/vega-selection-tile_2.entry.js +7 -8
  223. package/dist/esm/vega-sidenav_3.entry.js +16 -17
  224. package/dist/esm/vega-signature-capture.entry.js +14 -15
  225. package/dist/esm/vega-stepper.entry.js +7 -8
  226. package/dist/esm/vega-tab-group_2.entry.js +4 -5
  227. package/dist/esm/vega-table_8.entry.js +12 -13
  228. package/dist/esm/vega-textarea.entry.js +13 -8
  229. package/dist/esm/vega-time-picker_2.entry.js +22 -14
  230. package/dist/esm/vega-toggle-switch.entry.js +6 -7
  231. package/dist/esm/vega-tooltip_2.entry.js +12 -12
  232. package/dist/esm/vega.js +14 -12
  233. package/dist/types/components/vega-breadcrumb/slimmers/renderers/vega-breadcrumb-collapsed-item-renderer.d.ts +1 -1
  234. package/dist/types/components/vega-breadcrumb/slimmers/renderers/vega-breadcrumb-item-renderer.d.ts +2 -1
  235. package/dist/types/components/vega-breadcrumb/types.d.ts +1 -0
  236. package/dist/types/components/vega-breadcrumb/vega-breadcrumb.d.ts +2 -2
  237. package/dist/types/components/vega-button-link/vega-button-link.d.ts +5 -8
  238. package/dist/types/components/vega-input-numeric/slimmers/renderers/vega-input-numeric-renderer.d.ts +3 -0
  239. package/dist/types/components/vega-input-numeric/vega-input-numeric.d.ts +12 -0
  240. package/dist/types/components/vega-rich-text-content/vega-rich-text-content.d.ts +8 -0
  241. package/dist/types/components/vega-rich-text-editor/constants/constant.d.ts +2 -1
  242. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/action-handle-strategy-registry.d.ts +8 -0
  243. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/insert-node-to-nearest-root-strategy.d.ts +18 -0
  244. package/dist/types/components/vega-rich-text-editor/dto/actions/insert-node-to-nearest-root-action.d.ts +14 -0
  245. package/dist/types/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.d.ts +2 -1
  246. package/dist/types/components/vega-rich-text-editor/dto/actions/update-cursor-position-action.d.ts +4 -2
  247. package/dist/types/components/vega-rich-text-editor/dto/blocks/block.abstract.d.ts +2 -3
  248. package/dist/types/components/vega-rich-text-editor/dto/content-state.d.ts +6 -0
  249. package/dist/types/components/vega-rich-text-editor/dto/nodes/text-node.d.ts +11 -1
  250. package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/link-wrapper-renderer.d.ts +3 -3
  251. package/dist/types/components/vega-rich-text-editor/extensions/base-toolbar-button-renderer.d.ts +95 -2
  252. package/dist/types/components/vega-rich-text-editor/extensions/extension.abstract.d.ts +82 -0
  253. package/dist/types/components/vega-rich-text-editor/extensions/languages/language-extension.d.ts +50 -0
  254. package/dist/types/components/vega-rich-text-editor/extensions/languages/language-toolbar-button-renderer.d.ts +54 -0
  255. package/dist/types/components/vega-rich-text-editor/extensions/tokens/insert-token-node-action.d.ts +16 -0
  256. package/dist/types/components/vega-rich-text-editor/extensions/tokens/insert-token-node-strategy.d.ts +12 -0
  257. package/dist/types/components/vega-rich-text-editor/extensions/tokens/span-to-token-node-strategy.d.ts +24 -0
  258. package/dist/types/components/vega-rich-text-editor/extensions/tokens/token-extension.d.ts +14 -0
  259. package/dist/types/components/vega-rich-text-editor/extensions/tokens/token-node-renderer.d.ts +38 -0
  260. package/dist/types/components/vega-rich-text-editor/extensions/tokens/token-node.d.ts +39 -0
  261. package/dist/types/components/vega-rich-text-editor/extensions/tokens/token-toolbar-button-renderer.d.ts +47 -0
  262. package/dist/types/components/vega-rich-text-editor/interface.d.ts +52 -1
  263. package/dist/types/components/vega-rich-text-editor/public-api.d.ts +29 -0
  264. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/extension-controller.d.ts +44 -0
  265. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/helper/element-to-dto-strategy/element-to-dto-strategy.abstract.d.ts +10 -1
  266. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/toolbar-renderer.d.ts +6 -0
  267. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/toolbar-button-slimmer.abstract.d.ts +4 -4
  268. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/visual-mode-toolbar-button-slimmer.abstract.d.ts +7 -7
  269. package/dist/types/components/vega-rich-text-editor/vega-rich-text-editor.d.ts +10 -0
  270. package/dist/types/components/vega-textarea/vega-textarea.d.ts +6 -0
  271. package/dist/types/components/vega-time-picker/vega-time-picker.d.ts +8 -0
  272. package/dist/types/components.d.ts +59 -10
  273. package/dist/types/helpers/public-api.d.ts +1 -1
  274. package/dist/types/helpers/validator/rules/max-number-rule.d.ts +3 -1
  275. package/dist/types/helpers/validator/rules/min-number-rule.d.ts +3 -1
  276. package/dist/types/types/components.type.d.ts +1 -0
  277. package/dist/types/types/public-api.d.ts +11 -0
  278. package/dist/vega/index.esm.js +1 -1
  279. package/dist/vega/p-03cc47b7.entry.js +1 -0
  280. package/dist/vega/p-07836d27.entry.js +1 -0
  281. package/dist/vega/p-079f5d94.entry.js +1 -0
  282. package/dist/vega/p-09cb98f3.entry.js +1 -0
  283. package/dist/vega/{p-fb232e29.entry.js → p-0b91bb73.entry.js} +1 -1
  284. package/dist/vega/p-15a78afd.entry.js +1 -0
  285. package/dist/vega/p-16075b30.entry.js +1 -0
  286. package/dist/vega/{p-67101f43.entry.js → p-1c08077c.entry.js} +1 -1
  287. package/dist/vega/{p-c5e862aa.js → p-1da54ff3.js} +1 -1
  288. package/dist/vega/p-20a180e4.js +1 -0
  289. package/dist/vega/p-2591f217.entry.js +1 -0
  290. package/dist/vega/p-25ddb070.entry.js +1 -0
  291. package/dist/vega/p-2788afe7.entry.js +1 -0
  292. package/dist/vega/p-2a1b3108.entry.js +1 -0
  293. package/dist/vega/p-2ee4def0.js +1 -0
  294. package/dist/vega/p-2f88ba36.entry.js +1 -0
  295. package/dist/vega/{p-f2a1fe6a.js → p-39c185a5.js} +1 -1
  296. package/dist/vega/p-3b1bedaf.entry.js +1 -0
  297. package/dist/vega/p-3c96bbe1.entry.js +1 -0
  298. package/dist/vega/p-3cdbee7e.js +1 -0
  299. package/dist/vega/p-3d0d8a21.entry.js +1 -0
  300. package/dist/vega/p-3d53858c.entry.js +1 -0
  301. package/dist/vega/{p-927cab0c.entry.js → p-3f3bbaaa.entry.js} +2 -2
  302. package/dist/vega/p-42c364e0.entry.js +1 -0
  303. package/dist/vega/p-4f56a427.entry.js +1 -0
  304. package/dist/vega/p-4f5a2b0c.entry.js +1 -0
  305. package/dist/vega/p-51d40b0d.entry.js +1 -0
  306. package/dist/vega/p-5420c1d4.entry.js +1 -0
  307. package/dist/vega/p-56ff8559.entry.js +1 -0
  308. package/dist/vega/p-589b7ea3.entry.js +1 -0
  309. package/dist/vega/p-5d3c6a06.entry.js +1 -0
  310. package/dist/vega/p-5dec47da.entry.js +1 -0
  311. package/dist/vega/p-5f377954.js +1 -1
  312. package/dist/vega/p-6244b0ad.entry.js +1 -0
  313. package/dist/vega/p-63212cc1.js +1 -0
  314. package/dist/vega/p-6585cfd5.entry.js +1 -0
  315. package/dist/vega/p-6ba27010.js +1 -0
  316. package/dist/vega/{p-129f5938.js → p-6caa6bb2.js} +1 -1
  317. package/dist/vega/p-74ac2a48.js +1 -0
  318. package/dist/vega/p-76c7538a.entry.js +1 -0
  319. package/dist/vega/p-7d8eaca9.entry.js +1 -0
  320. package/dist/vega/p-7da6e7bd.js +1 -0
  321. package/dist/vega/p-81765b4b.entry.js +1 -0
  322. package/dist/vega/p-81fbf18f.entry.js +1 -0
  323. package/dist/vega/p-8682ee0a.entry.js +1 -0
  324. package/dist/vega/p-893d5dfa.js +1 -0
  325. package/dist/vega/p-8a484812.entry.js +1 -0
  326. package/dist/vega/p-8a6b820a.entry.js +1 -0
  327. package/dist/vega/p-8c9ea6f4.js +1 -0
  328. package/dist/vega/p-8e58d6cb.entry.js +1 -0
  329. package/dist/vega/p-8e812dca.entry.js +1 -0
  330. package/dist/vega/p-8f056ac2.js +1 -0
  331. package/dist/vega/{p-e66aef91.entry.js → p-9125ba84.entry.js} +1 -1
  332. package/dist/vega/p-92469fa1.entry.js +1 -0
  333. package/dist/vega/p-9b2d8516.entry.js +1 -0
  334. package/dist/vega/p-9ca0bdcc.js +1 -0
  335. package/dist/vega/p-a61e4bba.entry.js +1 -0
  336. package/dist/vega/p-a646b66d.js +1 -0
  337. package/dist/vega/p-a7b5f497.js +1 -0
  338. package/dist/vega/p-b1054e18.entry.js +1 -0
  339. package/dist/vega/p-b1a5ff74.entry.js +1 -0
  340. package/dist/vega/p-b32f7aac.entry.js +1 -0
  341. package/dist/vega/{p-dc6f45af.entry.js → p-baafe7d9.entry.js} +1 -1
  342. package/dist/vega/{p-3a6abcd7.entry.js → p-bb51e020.entry.js} +1 -1
  343. package/dist/vega/{p-e764acd5.js → p-bb61f015.js} +1 -1
  344. package/dist/vega/p-bc0ae89a.entry.js +1 -0
  345. package/dist/vega/p-bd39af8a.entry.js +1 -0
  346. package/dist/vega/{p-cd18f0fe.js → p-bdd9ef3b.js} +1 -1
  347. package/dist/vega/p-c08ba4d7.entry.js +1 -0
  348. package/dist/vega/{p-5f85811c.entry.js → p-c167fa41.entry.js} +1 -1
  349. package/dist/vega/{p-7ecf65ec.js → p-c2377afa.js} +1 -1
  350. package/dist/vega/p-c671f57e.js +1 -0
  351. package/dist/vega/p-c6a354b1.js +1 -0
  352. package/dist/vega/p-c7726252.js +1 -0
  353. package/dist/vega/p-ce1766fa.js +1 -0
  354. package/dist/vega/p-cfb2af9c.entry.js +1 -0
  355. package/dist/vega/{p-3bf95faf.entry.js → p-d2790023.entry.js} +2 -2
  356. package/dist/vega/p-d3bbfb1b.js +1 -0
  357. package/dist/vega/{p-5faa7313.entry.js → p-d9617358.entry.js} +1 -1
  358. package/dist/vega/p-d982babe.entry.js +1 -0
  359. package/dist/vega/p-da6369d4.entry.js +1 -0
  360. package/dist/vega/p-dcae53cf.entry.js +1 -0
  361. package/dist/vega/p-ddfad815.entry.js +1 -0
  362. package/dist/vega/p-e00ed9bd.entry.js +1 -0
  363. package/dist/vega/p-ebfc5739.entry.js +1 -0
  364. package/dist/vega/p-f0ff4463.js +1 -0
  365. package/dist/vega/{p-aeccc7f8.js → p-f1436035.js} +1 -1
  366. package/dist/vega/p-ff3a8907.entry.js +1 -0
  367. package/dist/vega/vega.esm.js +1 -1
  368. package/package.json +1 -1
  369. package/dist/cjs/dom-node-subject-observer-factory-15130e50.js +0 -45
  370. package/dist/cjs/internal-icon-manager-f8677abb.js +0 -55
  371. package/dist/collection/components/vega-breadcrumb/slimmers/controllers/vega-breadcrumb-click-controller.js +0 -43
  372. package/dist/esm/dom-node-subject-observer-factory-1e456cd4.js +0 -43
  373. package/dist/esm/internal-icon-manager-7eac52c8.js +0 -53
  374. package/dist/types/components/vega-breadcrumb/slimmers/controllers/vega-breadcrumb-click-controller.d.ts +0 -26
  375. package/dist/vega/p-0070e970.entry.js +0 -1
  376. package/dist/vega/p-0169af6b.entry.js +0 -1
  377. package/dist/vega/p-03e9cbc8.js +0 -1
  378. package/dist/vega/p-04341cd4.entry.js +0 -1
  379. package/dist/vega/p-0664ca9c.js +0 -1
  380. package/dist/vega/p-074b73f8.js +0 -1
  381. package/dist/vega/p-08fb66a4.entry.js +0 -1
  382. package/dist/vega/p-0cf35281.entry.js +0 -1
  383. package/dist/vega/p-0e75ddb2.entry.js +0 -1
  384. package/dist/vega/p-13cb5a04.entry.js +0 -1
  385. package/dist/vega/p-18223240.js +0 -1
  386. package/dist/vega/p-19ce9ae6.js +0 -1
  387. package/dist/vega/p-27f922fe.entry.js +0 -1
  388. package/dist/vega/p-2c7b7dd6.entry.js +0 -1
  389. package/dist/vega/p-310f9e76.entry.js +0 -1
  390. package/dist/vega/p-330d7ba8.js +0 -1
  391. package/dist/vega/p-34fdbe7a.js +0 -1
  392. package/dist/vega/p-3d6c302d.js +0 -1
  393. package/dist/vega/p-42563036.entry.js +0 -1
  394. package/dist/vega/p-441a681b.js +0 -1
  395. package/dist/vega/p-4a357f30.entry.js +0 -1
  396. package/dist/vega/p-4e68dfd9.js +0 -1
  397. package/dist/vega/p-4e8b6eb6.entry.js +0 -1
  398. package/dist/vega/p-50dd3cf1.js +0 -1
  399. package/dist/vega/p-518722aa.js +0 -1
  400. package/dist/vega/p-5422fdc4.entry.js +0 -1
  401. package/dist/vega/p-5c36a6cb.entry.js +0 -1
  402. package/dist/vega/p-5d095f9b.entry.js +0 -1
  403. package/dist/vega/p-68806f9c.entry.js +0 -1
  404. package/dist/vega/p-6cf490d9.entry.js +0 -1
  405. package/dist/vega/p-6def20e1.js +0 -1
  406. package/dist/vega/p-78d3f99b.entry.js +0 -1
  407. package/dist/vega/p-792715f3.js +0 -1
  408. package/dist/vega/p-7a201c6e.entry.js +0 -1
  409. package/dist/vega/p-7c22a1c3.entry.js +0 -1
  410. package/dist/vega/p-7f329473.entry.js +0 -1
  411. package/dist/vega/p-80f1b680.js +0 -1
  412. package/dist/vega/p-82beb586.entry.js +0 -1
  413. package/dist/vega/p-84eb131b.entry.js +0 -1
  414. package/dist/vega/p-8c46e116.js +0 -1
  415. package/dist/vega/p-909820dd.entry.js +0 -1
  416. package/dist/vega/p-989e141d.entry.js +0 -1
  417. package/dist/vega/p-a29e5d32.js +0 -1
  418. package/dist/vega/p-a3942d0b.entry.js +0 -1
  419. package/dist/vega/p-a66533c1.entry.js +0 -1
  420. package/dist/vega/p-a9b831d8.entry.js +0 -1
  421. package/dist/vega/p-b1d0e4cb.entry.js +0 -1
  422. package/dist/vega/p-b34f9891.entry.js +0 -1
  423. package/dist/vega/p-b820e42f.entry.js +0 -1
  424. package/dist/vega/p-c4677b0c.entry.js +0 -1
  425. package/dist/vega/p-c467fe81.entry.js +0 -1
  426. package/dist/vega/p-c7762c86.entry.js +0 -1
  427. package/dist/vega/p-c9e57cf1.entry.js +0 -1
  428. package/dist/vega/p-d0b3e319.entry.js +0 -1
  429. package/dist/vega/p-d7b4ffed.entry.js +0 -1
  430. package/dist/vega/p-e4586f13.entry.js +0 -1
  431. package/dist/vega/p-e71c4a09.entry.js +0 -1
  432. package/dist/vega/p-ea66d9f7.entry.js +0 -1
  433. package/dist/vega/p-ebbaa112.entry.js +0 -1
  434. package/dist/vega/p-ec6819fe.entry.js +0 -1
  435. package/dist/vega/p-ec9a8f81.entry.js +0 -1
  436. package/dist/vega/p-ed01328c.entry.js +0 -1
  437. package/dist/vega/p-ed798cd4.entry.js +0 -1
  438. package/dist/vega/p-edb71a72.entry.js +0 -1
  439. package/dist/vega/p-f08a4adf.js +0 -1
  440. package/dist/vega/p-f4e23c23.entry.js +0 -1
  441. package/dist/vega/p-f825e8a2.entry.js +0 -1
  442. package/dist/vega/p-f9deb43e.entry.js +0 -1
  443. package/dist/vega/p-fdd930a9.entry.js +0 -1
  444. package/dist/vega/p-fe52c370.entry.js +0 -1
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- const codeBlock = require('./code-block-ecb2df41.js');
3
+ const codeBlock = require('./code-block-eb66d852.js');
4
4
  const createPublicApiRuntimeMetricsSlimmer = require('./create-public-api-runtime-metrics-slimmer-e2e274e1.js');
5
5
  const typeGuard = require('./type-guard-f12b5bae.js');
6
- const changeManager = require('./change-manager-a297e4d2.js');
7
- const domNodeSubjectFactory = require('./dom-node-subject-factory-4eb1fec2.js');
8
- const vegaInternalEventId = require('./vega-internal-event-id-9647aaf8.js');
9
6
  const string = require('./string-39438062.js');
10
7
  const ui = require('./ui-4ce1fa08.js');
8
+ const changeManager = require('./change-manager-a297e4d2.js');
9
+ const domNodeSubjectObserverFactory = require('./dom-node-subject-observer-factory-58e3c010.js');
10
+ const vegaInternalEventId = require('./vega-internal-event-id-9647aaf8.js');
11
11
  const object = require('./object-e2e28e3d.js');
12
12
 
13
13
  /**
@@ -497,2006 +497,2080 @@ class BlockTransformToCodeBlockStrategy extends codeBlock.ActionHandleStrategy {
497
497
  }
498
498
 
499
499
  /**
500
- * Abstract class to define strategies for processing HTML elements
500
+ * Abstract class to define handler for generate the annotations
501
501
  */
502
- class ElementToDTOStrategy {
502
+ class AnnotationGeneratorStrategyAbstract {
503
503
  }
504
- /**
505
- * Class to represent the output of a strategy applied to HTML elements
506
- */
507
- class ElementToDTOStrategyOutput {
508
- constructor(currentStrategy, currentElements) {
509
- this.childrenOutput = [];
510
- this.currentStrategy = currentStrategy;
511
- this.currentElements = currentElements;
504
+
505
+ /** Handle bold annotation */
506
+ class BoldAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
507
+ /**
508
+ * @inheritDoc
509
+ */
510
+ canHandle(targetDto) {
511
+ return targetDto.name === 'RTETextNode';
512
512
  }
513
513
  /**
514
- * Set children output.
514
+ * Handle annotation.
515
515
  *
516
- * @param {ElementToDTOStrategyOutput[]} childrenOutput - children outputs.
516
+ * @param {HTMLElement} element - Current elements.
517
+ * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
518
+ * @returns {VegaRTETextAnnotations} - Annotation.
517
519
  */
518
- setChildrenOutput(childrenOutput) {
519
- this.childrenOutput = childrenOutput;
520
+ handle(element, parentAnnotations = {}) {
521
+ return this.isBold(element) || parentAnnotations.bold ? { bold: true } : {};
520
522
  }
521
523
  /**
522
- * Transform current output and children output to DTO
524
+ * Is bold element.
523
525
  *
524
- * @param {VegaRTETransformOptions} [options] - Options for transformation.
525
- * @returns {Nullable<RTEContentBlock>} - DTO.
526
+ * @param {HTMLElement} element - current element.
527
+ * @returns {boolean} - boolean.
526
528
  */
527
- toDto(options = { autoMatchFormat: true, skipCustomAnnotations: true }) {
528
- const currentBlock = this.currentStrategy.handle(this.currentElements, options);
529
- if (this.childrenOutput.length > 0 && currentBlock) {
530
- this.currentStrategy.appendChildBlocks(currentBlock, this.childrenOutput
531
- .map((childOutput) => childOutput.toDto(options))
532
- .filter(typeGuard.isNonNullable));
533
- }
534
- return currentBlock;
529
+ isBold(element) {
530
+ return (element.nodeName === 'STRONG' ||
531
+ element.nodeName === 'B' ||
532
+ element.style.fontWeight === 'bold' ||
533
+ element.style.fontWeight === '700' ||
534
+ element.classList.contains('v-rte--bold'));
535
535
  }
536
536
  }
537
537
 
538
- /**
539
- * Manager for registering and retrieving strategies that convert HTML elements to DTOs.
540
- */
541
- class elementToDTOClassStrategyManager {
542
- constructor() {
543
- this.elementToBlockStrategies = [];
544
- this.elementToNodeStrategies = [];
538
+ /** Handle custom attribute annotation */
539
+ class CustomAttributeAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
540
+ /**
541
+ * Can be handle.
542
+ *
543
+ * @param {RTEDtoClassPrototype} targetDto - Target DTO.
544
+ * @param {HtmlElementToAnnotationGenerateOptions} [options] - Options for annotation generator.
545
+ * @returns {boolean} - .
546
+ */
547
+ canHandle(targetDto, options) {
548
+ return !options.skipCustomAnnotations && !!targetDto;
545
549
  }
546
550
  /**
547
- * Registers a element to block strategy for converting HTML elements to DTOs. The new strategy is added to the beginning of the list to give it higher priority.
551
+ * Handle annotation.
548
552
  *
549
- * @param {ElementToDTOStrategy} strategy - The strategy to register.
553
+ * @param {HTMLElement} element - Current elements.
554
+ * @returns {VegaRTETextAnnotations} - Annotation.
550
555
  */
551
- registerElementToBlockStrategy(strategy) {
552
- if (!this.hasDuplicateStrategy(strategy, this.elementToBlockStrategies)) {
553
- this.elementToBlockStrategies.unshift(strategy);
554
- }
556
+ handle(element) {
557
+ const attributes = this.getAttributes(element);
558
+ return Object.keys(attributes).length > 0 ? { customAttribute: attributes } : {};
555
559
  }
556
560
  /**
557
- * Registers an element to node strategy for converting HTML elements to DTOs. The new strategy is added to the beginning of the list to give it higher priority.
561
+ * Obtain the custom attributes of element, excluding 'style' and 'class'.
558
562
  *
559
- * @param {ElementToDTOStrategy} strategy - The strategy to register.
563
+ * @param {HTMLElement} element - current element.
564
+ * @returns {Record<string, string>} - Record<string, string>.
560
565
  */
561
- registerElementToNodeStrategy(strategy) {
562
- if (!this.hasDuplicateStrategy(strategy, this.elementToNodeStrategies)) {
563
- this.elementToNodeStrategies.unshift(strategy);
564
- }
566
+ getAttributes(element) {
567
+ const attributeNames = element
568
+ .getAttributeNames()
569
+ .filter((attr) => attr !== 'style' && attr !== 'class' && this.isValidAttr(attr));
570
+ return attributeNames.reduce((acc, item) => {
571
+ acc[item] = element.getAttribute(item);
572
+ return acc;
573
+ }, {});
565
574
  }
566
575
  /**
567
- * Retrieves all registered element to block strategies for converting HTML elements to DTOs.
576
+ * Check if the attribute name is valid.
568
577
  *
569
- * @returns {ElementToDTOStrategy[]} - A set of all registered element to block strategies.
578
+ * @param {string} attr - Attribute name.
579
+ * @returns {boolean} - True if valid, false otherwise.
570
580
  */
571
- getElementToBlockStrategies() {
572
- return this.elementToBlockStrategies;
581
+ isValidAttr(attr) {
582
+ return /^[a-zA-Z_][\w-]*$/.test(attr);
573
583
  }
584
+ }
585
+
586
+ /** Handle custom class annotation */
587
+ class CustomClassAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
574
588
  /**
575
- * Retrieves all registered element to node strategies for converting HTML elements to DTOs.
589
+ * Can be handle.
576
590
  *
577
- * @returns {ElementToDTOStrategy[]} - A set of all registered element to node strategies.
591
+ * @param {RTEDtoClassPrototype} targetDto - Target DTO.
592
+ * @param {HtmlElementToAnnotationGenerateOptions} [options] - Options for annotation generator.
593
+ * @returns {boolean} - .
578
594
  */
579
- getElementToNodeStrategies() {
580
- return this.elementToNodeStrategies;
595
+ canHandle(targetDto, options) {
596
+ return !options.skipCustomAnnotations && !!targetDto;
581
597
  }
582
598
  /**
583
- * Checks if a strategy is already registered in the provided strategy list.
599
+ * Handle annotation.
584
600
  *
585
- * @param {ElementToDTOStrategy} strategy - The strategy to check for duplicates.
586
- * @param {ElementToDTOStrategy[]} strategyList - The list of strategies to check against.
587
- * @returns {boolean} - True if the strategy is a duplicate, false otherwise.
601
+ * @param {HTMLElement} element - Current elements.
602
+ * @returns {VegaRTETextAnnotations} - Annotation.
588
603
  */
589
- hasDuplicateStrategy(strategy, strategyList) {
590
- return strategyList.includes(strategy);
604
+ handle(element) {
605
+ const classes = this.getCustomClass(element);
606
+ return classes.length > 0 ? { customClass: classes } : {};
607
+ }
608
+ /**
609
+ * Get the custom class
610
+ *
611
+ * @param {HTMLElement} element - current element.
612
+ * @returns {string[]} - the class after .
613
+ */
614
+ getCustomClass(element) {
615
+ return element.classList
616
+ .toString()
617
+ .split(' ')
618
+ .filter((item) => !item.includes('v-rte') && item !== '');
591
619
  }
592
620
  }
593
- const ElementToDTOClassStrategyManager = new elementToDTOClassStrategyManager();
594
621
 
595
- /** Element to DTO processor */
596
- class ElementToDtoStrategyProcessor {
622
+ /** Handle custom style annotation */
623
+ class CustomStyleAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
597
624
  /**
598
- * Transform process.
625
+ * Can be handle.
599
626
  *
600
- * @param {HTMLElement[]} elements - Current elements.
601
- * @param {VegaRTETransformOptions} [options] - Options for transformation.
602
- * @returns {ElementToDTOStrategyOutput[]} - outputs.
627
+ * @param {RTEDtoClassPrototype} targetDto - Target DTO.
628
+ * @param {HtmlElementToAnnotationGenerateOptions} [options] - Options for annotation generator.
629
+ * @returns {boolean} - .
603
630
  */
604
- process(elements, options = { autoMatchFormat: true, skipCustomAnnotations: true }) {
605
- const strategies = this.getElementToBlockStrategies();
606
- const outputs = [];
607
- for (let i = 0; i < elements.length; i++) {
608
- if (this.isInvalidElement(elements[i]))
609
- continue;
610
- let canHandledCount = 0;
611
- for (const strategy of strategies) {
612
- canHandledCount = strategy.canHandle(elements, i, options);
613
- if (canHandledCount > 0) {
614
- const handledElements = elements.slice(i, i + canHandledCount);
615
- const output = new ElementToDTOStrategyOutput(strategy, handledElements);
616
- if (canHandledCount === 1 && strategy.shouldProceedToElementChildren()) {
617
- output.setChildrenOutput(this.process(Array.from(handledElements[0].childNodes), options));
618
- }
619
- outputs.push(output);
620
- i += canHandledCount - 1;
621
- break;
622
- }
623
- }
624
- if (canHandledCount === 0 && i < elements.length) {
625
- const elementChildren = Array.from(elements[i].childNodes);
626
- const childrenOutputs = this.process(Array.from(elementChildren), options);
627
- if (childrenOutputs.length > 0) {
628
- outputs.push(...childrenOutputs);
629
- }
630
- }
631
- }
632
- return outputs;
631
+ canHandle(targetDto, options) {
632
+ return !options.skipCustomAnnotations && !!targetDto;
633
633
  }
634
634
  /**
635
- * Checks if the given element is valid to parse.
635
+ * Handle annotation.
636
636
  *
637
- * @param {HTMLElement} element - The pasted element.
638
- * @returns {boolean} Is valid
637
+ * @param {HTMLElement} element - Current elements.
638
+ * @returns {VegaRTETextAnnotations} - Annotation.
639
639
  */
640
- isInvalidElement(element) {
641
- if (element.nodeType === Node.COMMENT_NODE)
642
- return true;
643
- return ['META', 'STYLE'].includes(element.nodeName);
640
+ handle(element) {
641
+ const styles = this.generateCustomStyleAnnotations(element);
642
+ return Object.keys(styles).length > 0 ? { customStyle: styles } : {};
644
643
  }
645
644
  /**
646
- * Get the register element to block strategies.
645
+ * Obtain and format the style of element.
647
646
  *
648
- * @returns {ElementToDTOStrategy[]} - The register element to block strategies.
647
+ * @param {HTMLElement} element - current element.
648
+ * @returns {AnnotationStyle} - Record<string, string>.
649
649
  */
650
- getElementToBlockStrategies() {
651
- return ElementToDTOClassStrategyManager.getElementToBlockStrategies();
650
+ generateCustomStyleAnnotations(element) {
651
+ const customStyle = element.getAttribute('style');
652
+ if (!customStyle)
653
+ return {};
654
+ const styleValue = customStyle.split(';').filter(Boolean);
655
+ return styleValue
656
+ .filter((key) => key !== ' ')
657
+ .map((key) => {
658
+ // to remove redundant quote pairs if needed, for example: ['fontFamily: "Roboto Mono"'] will be updated to ['fontFamily: Roboto Mono']
659
+ const styleObject = key.replace(/(['"])(.*?)\1/g, '$2').split(':');
660
+ const styleKey = string.dashCaseToCamel(styleObject[0].trim());
661
+ return {
662
+ [styleKey]: styleObject[1].trim().replace(';', ''),
663
+ };
664
+ })
665
+ .reduce((current, obj) => (Object.assign(Object.assign({}, current), obj)), {});
652
666
  }
653
667
  }
654
- const ElementToDtoStrategyProcessor$1 = new ElementToDtoStrategyProcessor();
655
668
 
656
- /**
657
- * Update the cursor position in the editor.
658
- */
659
- class UpdateCursorPositionStrategy extends codeBlock.ActionHandleStrategy {
669
+ /** Handle indent annotation */
670
+ class IndentAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
660
671
  /**
661
672
  * @inheritDoc
662
673
  */
663
- handleAction(action, target) {
664
- const { offset, nextFocusNode } = action;
665
- const host = codeBlock.stateEntityRenderingRegistry.getDOMByEntity(target);
666
- if (host) {
667
- changeManager.ChangeManager.notify(domNodeSubjectFactory.domNodeSubjectFactory.getSubject(host, vegaInternalEventId.VegaInternalUpdateRTECursorPosition), {
668
- node: nextFocusNode,
669
- offset,
670
- });
671
- }
674
+ canHandle(targetDto) {
675
+ return ['RTETextBlock', 'RTEListItemBlock', 'RTEListBlock'].includes(targetDto.name);
672
676
  }
673
- }
674
-
675
- /**
676
- * Append new block array or node array to block or VegaRTEContent instance strategy.
677
- */
678
- class AppendChildrenStrategy extends codeBlock.ActionHandleStrategy {
679
677
  /**
680
- * @inheritDoc
678
+ * Handle annotation.
679
+ *
680
+ * @param {HTMLElement} element - Current elements.
681
+ * @returns {VegaRTEBlockAnnotations} - Annotation.
681
682
  */
682
- handleAction(action, target) {
683
- const newBlocks = action.entityToBeAppended;
684
- if (target.children) {
685
- newBlocks.forEach((block) => {
686
- block.parent = target;
687
- });
688
- // This line is used to fix the typescript error `This expression is not callable`. https://github.com/microsoft/TypeScript/issues/44373
689
- const arrayFixed = target.children;
690
- target.children = arrayFixed.concat(newBlocks);
683
+ handle(element) {
684
+ const indent = this.getIndent(element);
685
+ return indent ? { indent: indent } : {};
686
+ }
687
+ /**
688
+ * Get indent of current element.
689
+ *
690
+ * @param {HTMLElement} element - current element.
691
+ * @returns {Nullable<number>} - Indent.
692
+ */
693
+ getIndent(element) {
694
+ const style = element.style;
695
+ let marginLeft;
696
+ if (style.marginLeft) {
697
+ marginLeft = style.marginLeft;
698
+ }
699
+ else if (style.margin) {
700
+ const margins = style.margin.split(' ');
701
+ switch (margins.length) {
702
+ case 4:
703
+ marginLeft = margins[3];
704
+ break;
705
+ case 2:
706
+ case 3:
707
+ marginLeft = margins[1];
708
+ break;
709
+ default:
710
+ marginLeft = margins[0];
711
+ break;
712
+ }
713
+ }
714
+ else {
715
+ return null;
691
716
  }
717
+ const marginLeftNumber = Number(marginLeft.replace('px', ''));
718
+ return marginLeftNumber && marginLeftNumber >= 0 ? Math.floor(marginLeftNumber / 16) : null;
692
719
  }
693
720
  }
694
721
 
695
- /**
696
- * Insert children at the front of the block strategy.
697
- */
698
- class InsertChildrenBeforeStrategy extends codeBlock.ActionHandleStrategy {
722
+ /** Handle text align annotation */
723
+ class TextAlignAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
699
724
  /**
700
- * @inheritDoc
725
+ * Can be handle.
726
+ *
727
+ * @param {RTEDtoClassPrototype} targetDto - Target DTO.
728
+ * @returns {boolean} - .
701
729
  */
702
- handleAction(action, target) {
703
- this.replaceElementWithElements(target, action.referChildren, [
704
- ...action.childrenToBeInserted,
705
- action.referChildren,
706
- ]);
730
+ canHandle(targetDto) {
731
+ return ['RTETextBlock', 'RTEListItemBlock', 'RTEListBlock'].includes(targetDto.name);
707
732
  }
708
733
  /**
709
- * Replaces a specific block or node with an array of blocks or nodes within RTEContentBlock array.
734
+ * Handle annotation.
710
735
  *
711
- * @param {RTEBlock | VegaRTEContent} target - The block or the VegaRTEContent instance.
712
- * @param {RTEBlock | RTENode} referElement - Used as a reference element to identify the element that needs to be replaced in the array.
713
- * @param {RTEBlock[] | RTENode[]} elements - An array of block or node objects that you want to replace the `referElement` with in the array.
736
+ * @param {HTMLElement} element - Current elements.
737
+ * @returns {VegaRTEBlockAnnotations} - Annotation.
714
738
  */
715
- replaceElementWithElements(target, referElement, elements) {
716
- if (target.children) {
717
- elements.forEach((block) => {
718
- block.parent = target;
719
- });
720
- const arrayFixed = target.children;
721
- target.children = arrayFixed.flatMap((block) => {
722
- if (block === referElement) {
723
- return elements;
724
- }
725
- else {
726
- return block;
727
- }
728
- });
739
+ handle(element) {
740
+ const textAlign = this.getTextAlign(element);
741
+ return textAlign ? { textAlign: textAlign } : {};
742
+ }
743
+ /**
744
+ * Get text align of current element.
745
+ *
746
+ * @param {HTMLElement} element - current element.
747
+ * @returns {Nullable<VegaRTEBlockAlignment>} - Text align.
748
+ */
749
+ getTextAlign(element) {
750
+ const classList = element.classList;
751
+ if (classList.contains(`v-rte--horizontal-alignment-left`)) {
752
+ return 'left';
753
+ }
754
+ else if (classList.contains(`v-rte--horizontal-alignment-center`)) {
755
+ return 'center';
756
+ }
757
+ else if (classList.contains(`v-rte--horizontal-alignment-right`)) {
758
+ return 'right';
759
+ }
760
+ else if (classList.contains(`v-rte--horizontal-alignment-justify`)) {
761
+ return 'justify';
762
+ }
763
+ const style = element.style;
764
+ switch (style.textAlign) {
765
+ case 'center':
766
+ return 'center';
767
+ case 'right':
768
+ return 'right';
769
+ case 'justify':
770
+ return 'justify';
771
+ case 'left':
772
+ return 'left';
773
+ default:
774
+ return null;
729
775
  }
730
776
  }
731
777
  }
732
778
 
733
- /**
734
- * Insert children at the front of the block strategy.
735
- */
736
- class InsertChildrenAfterStrategy extends InsertChildrenBeforeStrategy {
779
+ /** Handle code annotation */
780
+ class CodeAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
737
781
  /**
738
782
  * @inheritDoc
739
783
  */
740
- handleAction(action, target) {
741
- this.replaceElementWithElements(target, action.referChildren, [
742
- action.referChildren,
743
- ...action.childrenToBeInserted,
744
- ]);
745
- }
746
- }
747
-
748
- /**
749
- * Annotation for image
750
- */
751
- class ImageAnnotation extends codeBlock.NodeAnnotation {
752
- constructor(size, alt) {
753
- super();
754
- this.type = codeBlock.NodeAnnotationTypeEnum.IMAGE;
755
- this.size = size;
756
- this.alt = alt;
784
+ canHandle(targetDto) {
785
+ return targetDto.name === 'RTETextNode';
757
786
  }
758
787
  /**
759
- * Generate the map item for the annotation
788
+ * Handle annotation.
760
789
  *
761
- * @param {string} size - Image size
762
- * @param {string} alt - Image alt
763
- * @returns {[NodeAnnotationTypeEnum.IMAGE, ImageAnnotation]} Map item for the annotation
790
+ * @param {HTMLElement} element - Current elements.
791
+ * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
792
+ * @returns {VegaRTETextAnnotations} - Annotation.
764
793
  */
765
- static from(size, alt) {
766
- return [codeBlock.NodeAnnotationTypeEnum.IMAGE, new ImageAnnotation(size, alt)];
794
+ handle(element, parentAnnotations = {}) {
795
+ return this.isCode(element) || parentAnnotations.code ? { code: true } : {};
767
796
  }
768
797
  /**
769
- * Generate the JSON representation of the annotation
798
+ * Is code element.
770
799
  *
771
- * @returns {Nullable<Record<string, unknown>>} JSON representation of the annotation
800
+ * @param {HTMLElement} element - current element.
801
+ * @returns {boolean} - boolean.
772
802
  */
773
- toJSON() {
774
- return typeGuard.isNonNullable(this.alt)
775
- ? {
776
- size: this.size,
777
- alt: this.alt,
778
- }
779
- : {
780
- size: this.size,
781
- };
803
+ isCode(element) {
804
+ return (element.classList.contains('v-rte--code') ||
805
+ element.nodeName === 'CODE' ||
806
+ element.nodeName === 'PRE' ||
807
+ element.style.fontFamily === 'monospace' ||
808
+ element.style.fontFamily.replace(/["']/g, '') === 'Roboto Mono');
782
809
  }
810
+ }
811
+
812
+ /** Handle color annotation */
813
+ class ColorAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
783
814
  /**
784
815
  * @inheritDoc
785
816
  */
786
- clone() {
787
- return new ImageAnnotation(this.size, this.alt);
817
+ canHandle(targetDto) {
818
+ return targetDto.name === 'RTETextNode';
788
819
  }
789
820
  /**
790
- * @inheritDoc
821
+ * Handle annotation.
822
+ *
823
+ * @param {HTMLElement} element - Current elements.
824
+ * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
825
+ * @returns {VegaRTETextAnnotations} - Annotation.
791
826
  */
792
- renderClass(options) {
793
- if (options === null || options === void 0 ? void 0 : options.standalone)
794
- return null;
795
- return this.size ? `v-rte--image-size-${this.size}` : null;
827
+ handle(element, parentAnnotations = {}) {
828
+ const color = this.getColor(element) || parentAnnotations.textColor;
829
+ return color ? { textColor: color } : {};
796
830
  }
797
831
  /**
798
- * @inheritDoc
832
+ * Get current color of element.
833
+ *
834
+ * @param {HTMLElement} element - current element.
835
+ * @returns {Nullable<string>} - color.
799
836
  */
800
- renderStyle(options) {
801
- if (!(options === null || options === void 0 ? void 0 : options.standalone))
837
+ getColor(element) {
838
+ var _a;
839
+ const color = element.style.color;
840
+ const hexColor = (_a = ui.rgbToHex(color)) === null || _a === void 0 ? void 0 : _a.toUpperCase();
841
+ if (hexColor) {
842
+ // We don't display default text color as inline style, because we defined it in the vega-rich-text-content.scss.
843
+ const colorSchema = codeBlock.RTE_TEXT_COLORS.filter((item) => item.key !== codeBlock.RTE_DEFAULT_TEXT_COLOR.key).find((schema) => schema.light === hexColor || schema.dark === hexColor);
844
+ if (colorSchema)
845
+ return colorSchema.key;
802
846
  return null;
803
- const baseStyle = { verticalAlign: 'bottom' };
804
- switch (this.size) {
805
- case 'sm': {
806
- return Object.assign(Object.assign({}, baseStyle), { width: '25%' });
807
- }
808
- case 'md': {
809
- return Object.assign(Object.assign({}, baseStyle), { width: '50%' });
810
- }
811
- case 'lg': {
812
- return Object.assign(Object.assign({}, baseStyle), { width: '100%' });
847
+ }
848
+ else {
849
+ for (const color of codeBlock.RTE_TEXT_COLORS) {
850
+ if (element.style.color.includes(color.key)) {
851
+ return color.key;
852
+ }
813
853
  }
854
+ return null;
814
855
  }
815
856
  }
816
857
  }
817
858
 
818
- /**
819
- * Update the image node annotation map strategy.
820
- */
821
- class ImageSetAnnotationMapStrategy extends codeBlock.ActionHandleStrategy {
859
+ /** Handle italic annotation */
860
+ class ItalicAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
822
861
  /**
823
862
  * @inheritDoc
824
863
  */
825
- handleAction(action, target) {
826
- const annotation = action.toAnnotation();
827
- target.annotationMap.set(annotation.type, annotation);
864
+ canHandle(targetDto) {
865
+ return targetDto.name === 'RTETextNode';
828
866
  }
829
- }
830
-
831
- /**
832
- * The image node update property url strategy.
833
- */
834
- class ImageUpdateUrlStrategy extends codeBlock.ActionHandleStrategy {
835
867
  /**
836
- * @inheritDoc
868
+ * Handle annotation.
869
+ *
870
+ * @param {HTMLElement} element - Current elements.
871
+ * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
872
+ * @returns {VegaRTETextAnnotations} - Annotation.
837
873
  */
838
- handleAction(action, target) {
839
- target.url = action.url;
874
+ handle(element, parentAnnotations = {}) {
875
+ return this.isItalic(element) || parentAnnotations.italic ? { italic: true } : {};
876
+ }
877
+ /**
878
+ * Is italic element.
879
+ *
880
+ * @param {HTMLElement} element - current element.
881
+ * @returns {boolean} - boolean.
882
+ */
883
+ isItalic(element) {
884
+ return (element.nodeName === 'I' ||
885
+ element.style.fontStyle === 'italic' ||
886
+ element.nodeName === 'EM' ||
887
+ element.classList.contains('v-rte--italic'));
840
888
  }
841
889
  }
842
890
 
843
- var __rest = (undefined && undefined.__rest) || function (s, e) {
844
- var t = {};
845
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
846
- t[p] = s[p];
847
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
848
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
849
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
850
- t[p[i]] = s[p[i]];
851
- }
852
- return t;
853
- };
854
- /**
855
- * Image node
856
- */
857
- class RTEImageNode extends codeBlock.RTEDecoratorNode {
858
- constructor(id, url, parentBlock, annotationMap) {
859
- super(id, annotationMap);
860
- this.type = codeBlock.NodeTypeEnum.IMAGE;
861
- this.url = url;
862
- this.parent = parentBlock;
891
+ /** Handle link annotation */
892
+ class LinkAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
893
+ constructor() {
894
+ super(...arguments);
895
+ this.handlers = [
896
+ new CustomAttributeAnnotationHandler(),
897
+ new CustomClassAnnotationHandler(),
898
+ new CustomStyleAnnotationHandler(),
899
+ ];
863
900
  }
864
901
  /**
865
- * Converts a VegaRTEImageNode into an RTEImageNode by mapping nodes and creating annotations.
902
+ * Can be handle.
866
903
  *
867
- * @param {VegaRTEImageNode} node - The node to be converted.
868
- * @param {RTEImageBlock} parentBlock - The parent block
869
- * @param {VegaRTETransformOptions} options - Optional transformation options.
870
- * @returns {RTEImageNode} An instance of `RTEImageBlock`
904
+ * @param {RTEDtoClassPrototype} targetDto - Target DTO.
905
+ * @returns {boolean} - .
871
906
  */
872
- static from(node, parentBlock, options = { autoMatchFormat: true }) {
873
- const imageNode = new RTEImageNode(node.id, node.url, parentBlock);
874
- const autoMatchFormat = !!options.autoMatchFormat;
875
- const _a = Object.assign({}, node.annotations), { size } = _a, otherAnnotations = __rest(_a, ["size"]);
876
- const annotations = Object.assign(Object.assign({}, otherAnnotations), { size: size !== null && size !== void 0 ? size : (autoMatchFormat ? 'md' : undefined) });
877
- imageNode.annotationMap = new Map(Object.keys(annotations)
878
- .map((type) => {
879
- if (type === 'size' || type === 'alt') {
880
- return ImageAnnotation.from(annotations.size, annotations.alt);
881
- }
882
- return this.createAnnotationEntity(type, annotations[type]);
883
- })
884
- .filter(typeGuard.isNonNullable));
885
- return imageNode;
907
+ canHandle(targetDto) {
908
+ return targetDto.name === 'RTETextNode';
886
909
  }
887
910
  /**
888
- * @inheritDoc
911
+ * Handle annotation.
912
+ *
913
+ * @param {HTMLElement} element - Current elements.
914
+ * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
915
+ * @returns {VegaRTETextAnnotations} - Annotation.
889
916
  */
890
- toJSON() {
891
- const annotations = Array.from(this.annotationMap.values())
892
- .filter((annotation) => annotation instanceof ImageAnnotation || annotation instanceof codeBlock.CommonAnnotation)
893
- .reduce((record, annotation) => {
894
- return Object.assign(Object.assign({}, record), annotation.toJSON());
895
- }, {});
896
- if (annotations.alt == '')
897
- delete annotations.alt;
898
- return Object.assign(Object.assign({ id: this.id }, (Object.keys(annotations).length > 0 ? { annotations } : {})), { type: 'image', url: this.url });
917
+ handle(element, parentAnnotations = {}) {
918
+ if (parentAnnotations.link)
919
+ return { link: parentAnnotations.link };
920
+ return element.tagName === 'A' ? { link: this.generateLinkAnnotations(element) } : {};
899
921
  }
900
922
  /**
901
- * @inheritDoc
923
+ * Generate link annotations.
924
+ *
925
+ * @param {HTMLElement} element - Current elements.
926
+ * @returns {VegaRTELink} - link annotations.
902
927
  */
903
- clone() {
904
- return new RTEImageNode(this.id, this.url, this.parent, super.cloneAnnotations());
928
+ generateLinkAnnotations(element) {
929
+ const annotations = {
930
+ href: element.getAttribute('href') || '',
931
+ groupKey: createPublicApiRuntimeMetricsSlimmer.generateUUID(),
932
+ };
933
+ this.handlers.forEach((handler) => {
934
+ Object.assign(annotations, handler.handle(element));
935
+ });
936
+ return annotations;
905
937
  }
938
+ }
939
+
940
+ /** Handle strike through annotation */
941
+ class StrikeThroughAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
906
942
  /**
907
943
  * @inheritDoc
908
944
  */
909
- toHtml() {
910
- const imageAnnotation = this.getAnnotationByType(codeBlock.NodeAnnotationTypeEnum.IMAGE);
911
- const attrStr = super.generateAttributeString(...[
912
- imageAnnotation && imageAnnotation.alt ? `alt="${imageAnnotation.alt}"` : null,
913
- `src="${this.url}"`,
914
- imageAnnotation && imageAnnotation.size ? `data-size="${imageAnnotation.size}"` : null,
915
- ].filter(typeGuard.isNonNullable));
916
- return `<img${attrStr}>`;
945
+ canHandle(targetDto) {
946
+ return targetDto.name === 'RTETextNode';
917
947
  }
918
948
  /**
919
- * @inheritDoc
949
+ * Handle annotation.
950
+ *
951
+ * @param {HTMLElement} element - Current elements.
952
+ * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
953
+ * @returns {VegaRTETextAnnotations} - Annotation.
920
954
  */
921
- doAnnotationActionApply(action) {
922
- const strategy = codeBlock.ActionHandleStrategyRegistry.get(codeBlock.AnnotationAction.name, RTEImageNode.name);
923
- if (strategy) {
924
- strategy.execute(action, this);
925
- }
955
+ handle(element, parentAnnotations = {}) {
956
+ return this.isStrikethrough(element) || parentAnnotations.strikethrough
957
+ ? { strikethrough: true }
958
+ : {};
926
959
  }
927
960
  /**
928
- * @inheritDoc
961
+ * Is strikethrough element.
962
+ *
963
+ * @param {HTMLElement} element - current element.
964
+ * @returns {boolean} - boolean.
929
965
  */
930
- doModifyActionApply(action) {
931
- codeBlock.ActionHandleStrategyRegistry.executeTheStrategy(action, this);
966
+ isStrikethrough(element) {
967
+ return (element.style.textDecoration.includes('line-through') ||
968
+ element.nodeName === 'S' ||
969
+ element.nodeName === 'DEL' ||
970
+ element.classList.contains('v-rte--strikethrough'));
932
971
  }
933
972
  }
934
- (() => {
935
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.UPDATE_IMAGE_NODE_URL, RTEImageNode.name, new ImageUpdateUrlStrategy());
936
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.AnnotationAction.name, RTEImageNode.name, new ImageSetAnnotationMapStrategy());
937
- })();
938
973
 
939
- /**
940
- * Split the current image block with a special position strategy.
941
- */
942
- class BlockSplitWithImageNodeStrategy extends codeBlock.ActionHandleStrategy {
974
+ /** Handle underline annotation */
975
+ class UnderlineAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
943
976
  /**
944
977
  * @inheritDoc
945
978
  */
946
- handleAction(action, target) {
947
- action.newBlock = this.splitImageNodes(action.splitPointNode, action.startOffsetOfNode, target);
979
+ canHandle(targetDto) {
980
+ return targetDto.name === 'RTETextNode';
948
981
  }
949
982
  /**
950
- * The image offset should be 0 or 1
951
- * <vega-rich-text-image-editor><img /></vega-rich-text-image-editor>
983
+ * Handle annotation.
952
984
  *
953
- * @param {RTEImageNode} imageNode The split point image node.
954
- * @param {number} imageOffset The cursor point 0 | 1.
955
- * @param {RTEImageBlock} target The image block.
956
- * @returns {Nullable<RTEBlock>} The new block after split
985
+ * @param {HTMLElement} element - Current elements.
986
+ * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
987
+ * @returns {VegaRTETextAnnotations} - Annotation.
957
988
  */
958
- splitImageNodes(imageNode, imageOffset, target) {
959
- const nodesSplitIndex = target.children.indexOf(imageNode);
960
- if (nodesSplitIndex > -1) {
961
- const beforeNodes = target.children.slice(0, nodesSplitIndex + imageOffset);
962
- const afterNodes = target.children.slice(nodesSplitIndex + imageOffset);
963
- target.apply(new codeBlock.ReplaceChildNodesAction(beforeNodes));
964
- const newBlock = this.cloneWithNodes(afterNodes, target);
965
- target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newBlock));
966
- return newBlock;
967
- }
989
+ handle(element, parentAnnotations = {}) {
990
+ return this.isUnderline(element) || parentAnnotations.underline ? { underline: true } : {};
968
991
  }
969
992
  /**
970
- * Creates a new RTEImageBlock instance with the provided RTEImageNode instances appended to it.
993
+ * Is underline element.
971
994
  *
972
- * @param {RTEImageNode[]} nodes - An array of RTEImageNode objects that will be used to create a new RTEImageBlock instance.
973
- * @param {RTEImageBlock} target The image block.
974
- * @returns {RTEImageBlock} A new `RTEImageBlock` object with the provided `nodes` appended to it.
995
+ * @param {HTMLElement} element - current element.
996
+ * @returns {boolean} - boolean.
975
997
  */
976
- cloneWithNodes(nodes, target) {
977
- const block = target.createNewImageBlock();
978
- block.children = [];
979
- block.apply(new codeBlock.AppendChildrenAction(nodes));
980
- return block;
981
- }
982
- }
983
-
984
- /**
985
- * Break the current block after press enter, this action is similar with the SplitBlockWithNodeAction,
986
- * The SplitBlockWithNodeAction split the current block to two same type blocks, but this action will create new paragraph or list item when break at start or end.
987
- * The property `newBlock` use to store the new create block if need.
988
- *
989
- * @example currentBlock.apply(new InsertNewParagraphAction(startContainerNode, startOffset))
990
- */
991
- class InsertNewParagraphAction extends codeBlock.ModifyContentAction {
992
- constructor(startContainerNode, startOffset) {
993
- super();
994
- this.type = codeBlock.ModifyContentActionType.INSERT_NEW_PARAGRAPH;
995
- this.startContainerNode = startContainerNode;
996
- this.startOffset = startOffset;
998
+ isUnderline(element) {
999
+ return (element.style.textDecoration.includes('underline') ||
1000
+ element.nodeName === 'U' ||
1001
+ element.nodeName === 'INS' ||
1002
+ element.classList.contains('v-rte--underline'));
997
1003
  }
998
1004
  }
999
1005
 
1000
- /**
1001
- * The image block insert line break strategy.
1002
- */
1003
- class ImageInsertLineBreakStrategy extends codeBlock.ActionHandleStrategy {
1006
+ /** Handle text style annotation */
1007
+ class TextStyleAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1004
1008
  /**
1005
- * The image block not support insert the line break node, so invoke the insert new paragraph logic directly.
1009
+ * Can be handle.
1006
1010
  *
1007
- * @param {LineBreakSingleBlockAction} action - The action instance.
1008
- * @param {RTEImageBlock} target - The image block.
1011
+ * @param {RTEDtoClassPrototype} targetDto - Target DTO.
1012
+ * @param {HtmlElementToAnnotationGenerateOptions} options - Options for annotation generator.
1013
+ * @returns {boolean} - .
1009
1014
  */
1010
- handleAction(action, target) {
1011
- const insertNewParagraphAction = new InsertNewParagraphAction(action.startContainerNode, action.startOffset);
1012
- target.apply(insertNewParagraphAction);
1013
- const newBlock = insertNewParagraphAction.newBlock;
1014
- if (newBlock) {
1015
- action.lineBreakNode = newBlock.children[0];
1016
- }
1015
+ canHandle(targetDto, options) {
1016
+ return !!options.autoMatchFormat && targetDto.name === 'RTETextBlock';
1017
1017
  }
1018
- }
1019
-
1020
- /**
1021
- * Insert a line break node into multiple blocks selection at special position strategy.
1022
- */
1023
- class ImageInsertLineBreakWithBlocksStrategy extends codeBlock.ActionHandleStrategy {
1024
1018
  /**
1025
- * @inheritDoc
1019
+ * Handle annotation.
1020
+ *
1021
+ * @param {HTMLElement} element - Current elements.
1022
+ * @returns {VegaRTETextBlockAnnotations} - Annotation.
1026
1023
  */
1027
- handleAction(action, target) {
1028
- action.lineBreakNode = this.lineBreakMultipleBlocks(action.selectedBlocks, target);
1024
+ handle(element) {
1025
+ const textStyle = this.getTextStyle(element);
1026
+ return textStyle ? { textStyle: textStyle } : {};
1029
1027
  }
1030
1028
  /**
1031
- * Inserts a new paragraph block with a line break after a selected block of text in a rich text editor.
1029
+ * Get the node type of element. The element type is determined in the following
1030
+ * order: "data-type" attribute, node name, font size and class name.
1032
1031
  *
1033
- * @param {RTEBlock[]} selectedBlocks - An array of RTEBlock objects that represent the blocks that have been selected for a specific action in the Rich Text Editor.
1034
- * @param {RTEImageBlock} target - The image block.
1035
- * @returns {Nullable<RTETextNode>} Returns a Nullable RTETextNode.
1032
+ * @param {HTMLElement} element - element.
1033
+ * @returns {Nullable<VegaRTETextStyleType>} - node type.
1036
1034
  */
1037
- lineBreakMultipleBlocks(selectedBlocks, target) {
1038
- const newParagraph = codeBlock.RTETextBlock.from({
1039
- id: createPublicApiRuntimeMetricsSlimmer.generateUUID(),
1040
- type: 'paragraph',
1041
- nodes: [{ id: createPublicApiRuntimeMetricsSlimmer.generateUUID(), type: 'text', text: '\n' }],
1042
- });
1043
- target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newParagraph));
1044
- const afterNodes = this.concatBlocksNodes(selectedBlocks.slice(1));
1045
- if (afterNodes.length === 0 || (afterNodes[0] && afterNodes[0].text === '')) {
1046
- afterNodes.push(new codeBlock.RTETextNode(createPublicApiRuntimeMetricsSlimmer.generateUUID(), '\n', newParagraph));
1047
- }
1048
- newParagraph.apply(new codeBlock.AppendChildrenAction(afterNodes));
1049
- return newParagraph['children'][0];
1035
+ getTextStyle(element) {
1036
+ const byDataType = this.getElementTypeByDataType(element);
1037
+ if (byDataType)
1038
+ return byDataType;
1039
+ const byNodeName = this.getElementTypeByNodeName(element);
1040
+ if (byNodeName)
1041
+ return byNodeName;
1042
+ const byFontSize = this.getElementTypeByFontSize(element);
1043
+ if (byFontSize)
1044
+ return byFontSize;
1045
+ const byClassName = this.getElementTypeByClassName(element);
1046
+ if (byClassName)
1047
+ return byClassName;
1048
+ return null;
1050
1049
  }
1051
1050
  /**
1052
- * Concat the child nodes of multiple RTEBlocks if both are not images.
1051
+ * Get the element type by data-type attribute.
1053
1052
  *
1054
- * @param {RTEBlock[]} blocks - multiple block of content in a rich text editor, such as a paragraph, heading, image, etc.
1055
- * @returns {RTENode[]} Array of connected block nodes
1053
+ * @param {HTMLElement} element - element.
1054
+ * @returns {Nullable<VegaRTETextStyleType>} - element type or null if not found.
1056
1055
  */
1057
- concatBlocksNodes(blocks) {
1058
- const nodes = [];
1059
- blocks.map((block) => {
1060
- if (block.type !== 'image') {
1061
- nodes.push(...block.children);
1062
- block.parent.apply(new codeBlock.RemoveChildrenAction(block));
1063
- }
1064
- });
1065
- return nodes;
1056
+ getElementTypeByDataType(element) {
1057
+ if (element.nodeType !== Node.TEXT_NODE && element.hasAttribute('data-type')) {
1058
+ return element.getAttribute('data-type');
1059
+ }
1060
+ return null;
1066
1061
  }
1067
- }
1068
-
1069
- /**
1070
- * Insert a image node at the special position of image block.
1071
- */
1072
- class ImageBlockInsertImageStrategy extends codeBlock.ActionHandleStrategy {
1073
1062
  /**
1074
- * @inheritDoc
1063
+ * Get the element type by font size.
1064
+ *
1065
+ * @param {HTMLElement} element - element.
1066
+ * @returns {Nullable<VegaRTETextStyleType>} - element type or null if not found.
1075
1067
  */
1076
- handleAction(action, target) {
1077
- const splitNode = action.splitPointNode;
1078
- const startOffsetOfNode = action.startOffsetOfNode;
1079
- const newImageBlock = action.imageBlockToBeInserted;
1080
- const newImageNodes = newImageBlock.children;
1081
- if (target.children.length < 1) {
1082
- target.apply(new codeBlock.AppendChildrenAction(newImageNodes));
1083
- }
1084
- else if (this.isCaretPositionAtBlockEnd(target, splitNode, startOffsetOfNode)) {
1085
- target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newImageBlock));
1086
- }
1087
- else if (this.isCaretPositionAtBlockStart(target, splitNode, startOffsetOfNode)) {
1088
- target.parent.apply(new codeBlock.InsertChildrenBeforeAction(target, newImageBlock));
1089
- }
1090
- else {
1091
- target.apply(new codeBlock.SplitBlockWithNodeAction(splitNode, startOffsetOfNode));
1092
- target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newImageBlock));
1068
+ getElementTypeByFontSize(element) {
1069
+ var _a;
1070
+ switch ((_a = element.style) === null || _a === void 0 ? void 0 : _a.fontSize) {
1071
+ case '36px':
1072
+ return 'title';
1073
+ case '28px':
1074
+ return 'subtitle';
1075
+ case '22px':
1076
+ return 'heading-1';
1077
+ case '20px':
1078
+ return 'heading-2';
1079
+ case '18px':
1080
+ return 'heading-3';
1081
+ default:
1082
+ return null;
1093
1083
  }
1094
1084
  }
1095
- }
1096
-
1097
- /**
1098
- * Image block
1099
- */
1100
- class RTEImageBlock extends codeBlock.RTEBlock {
1101
- constructor(id) {
1102
- super(id);
1103
- this.type = 'image';
1104
- this.children = [];
1105
- }
1106
1085
  /**
1107
- * Converts a VegaRTEImageBlock object into an RTEImageBlock object by mapping nodes and creating annotations.
1086
+ * Get the element type by node name.
1108
1087
  *
1109
- * @param {VegaRTEImageBlock} block - The block object to be converted.
1110
- * @param {VegaRTETransformOptions} options - Optional transformation options.
1111
- * @returns {RTEImageBlock} An instance of `RTEImageBlock`
1088
+ * @param {HTMLElement} element - element.
1089
+ * @returns {Nullable<VegaRTETextStyleType>} - element type or null if not found.
1112
1090
  */
1113
- static from(block, options = { autoMatchFormat: true }) {
1114
- const imageBlock = new RTEImageBlock(block.id);
1115
- const { annotations } = block;
1116
- imageBlock.children = block.nodes.map((image) => RTEImageNode.from(image, imageBlock, options));
1117
- if (annotations) {
1118
- super.convertAnnotationsToMap(imageBlock.annotationMap, annotations);
1091
+ getElementTypeByNodeName(element) {
1092
+ switch (element.nodeName) {
1093
+ case 'H1':
1094
+ return 'heading-1';
1095
+ case 'H2':
1096
+ return 'heading-2';
1097
+ case 'H3':
1098
+ return 'heading-3';
1099
+ case 'H4':
1100
+ return 'heading-4';
1101
+ case 'H5':
1102
+ return 'heading-5';
1103
+ case 'H6':
1104
+ return 'heading-6';
1105
+ default:
1106
+ return null;
1119
1107
  }
1120
- return imageBlock;
1121
1108
  }
1122
1109
  /**
1123
- * @inheritDoc
1110
+ * Get the element type by class name.
1111
+ *
1112
+ * @param {HTMLElement} element - element.
1113
+ * @returns {Nullable<VegaRTETextStyleType>} - element type or null if not found.
1124
1114
  */
1125
- toJSON() {
1126
- return Object.assign(Object.assign({}, super.toJSON()), { type: 'image', nodes: this.children.map((node) => node.toJSON()) });
1115
+ getElementTypeByClassName(element) {
1116
+ if (element.className) {
1117
+ const match = /\bv-rte--text-style-(title|subtitle|heading-1|heading-2|heading-3|paragraph)\b/.exec(element.className);
1118
+ if (match) {
1119
+ return match[1];
1120
+ }
1121
+ }
1122
+ return null;
1127
1123
  }
1124
+ }
1125
+
1126
+ /** Handle image size annotation */
1127
+ class ImageSizeAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1128
1128
  /**
1129
1129
  * @inheritDoc
1130
1130
  */
1131
- toHtml() {
1132
- const attrStr = super.generateAttributeString();
1133
- const children = this.children.map((node) => node.toHtml()).join('');
1134
- return super.shouldRenderAsInternalWrapper()
1135
- ? children
1136
- : [`<div${attrStr}>`, children, `</div>`].join('');
1131
+ canHandle(targetDto) {
1132
+ return targetDto.name === 'RTEImageNode';
1137
1133
  }
1138
1134
  /**
1139
- * @inheritDoc
1135
+ * Handle annotation.
1136
+ *
1137
+ * @param {HTMLElement} element - Current elements.
1138
+ * @returns {VegaRTEImageAnnotations} - Annotation.
1140
1139
  */
1141
- isNotEmpty() {
1142
- return this.children.length > 0 && this.children.some((node) => node.url.length > 0);
1140
+ handle(element) {
1141
+ const size = this.getImageSize(element);
1142
+ return size ? { size: size } : {};
1143
1143
  }
1144
1144
  /**
1145
- * @inheritDoc
1145
+ * Determine the image display size based on the width of the current element.
1146
+ *
1147
+ * @param {HTMLElement} element - current element.
1148
+ * @returns {Nullable<VegaRichTextImageEditorSizeType>} -Image size, default 'md'.
1146
1149
  */
1147
- getLastNode() {
1148
- return this.children[this.children.length - 1];
1150
+ getImageSize(element) {
1151
+ if (element.getAttribute('data-size')) {
1152
+ return element.getAttribute('data-size');
1153
+ }
1154
+ return null;
1149
1155
  }
1156
+ }
1157
+
1158
+ /** Handle image alt annotation */
1159
+ class ImageAltAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1150
1160
  /**
1151
- * Create a new image block.
1152
- *
1153
- * @returns {RTEImageBlock} - The empty image block.
1161
+ * @inheritDoc
1154
1162
  */
1155
- createNewImageBlock() {
1156
- return new RTEImageBlock(createPublicApiRuntimeMetricsSlimmer.generateUUID());
1163
+ canHandle(targetDto) {
1164
+ return targetDto.name === 'RTEImageNode';
1157
1165
  }
1158
1166
  /**
1159
- * @inheritDoc
1167
+ * Handle annotation.
1168
+ *
1169
+ * @param {HTMLElement} element - Current elements.
1170
+ * @returns {VegaRTEImageAnnotations} - Annotation.
1160
1171
  */
1161
- clone() {
1162
- const clonedBlock = new RTEImageBlock(this.id);
1163
- clonedBlock.children = this.children.map((node) => {
1164
- const clonedNode = node.clone();
1165
- clonedNode.parent = clonedBlock;
1166
- return clonedNode;
1167
- });
1168
- clonedBlock.annotationMap = super.cloneAnnotations();
1169
- clonedBlock.parent = this.parent;
1170
- return clonedBlock;
1172
+ handle(element) {
1173
+ return element.hasAttribute('alt') ? { alt: element.getAttribute('alt') } : {};
1171
1174
  }
1172
1175
  }
1173
- (() => {
1174
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.MERGE_TWO_BLOCKS_NODES, RTEImageBlock.name, new codeBlock.BlockMergeNodesStrategy());
1175
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.REPLACE_CHILD_NODES, RTEImageBlock.name, new codeBlock.BlockReplaceNodesStrategy());
1176
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.SPLIT_BLOCK_WITH_NODE, RTEImageBlock.name, new BlockSplitWithImageNodeStrategy());
1177
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.LINE_BREAK_SINGLE_BLOCK, RTEImageBlock.name, new ImageInsertLineBreakStrategy());
1178
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.LINE_BREAK_MULTIPLE_BLOCKS, RTEImageBlock.name, new ImageInsertLineBreakWithBlocksStrategy());
1179
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_IMAGE_TO_BLOCK, RTEImageBlock.name, new ImageBlockInsertImageStrategy());
1180
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.HorizontalAlignmentAnnotationAction.name, RTEImageBlock.name, new codeBlock.BlockUpdateHorizontalAlignmentStrategy());
1181
- })();
1182
1176
 
1183
1177
  /**
1184
- * HTML Block
1178
+ * Handle inline html annotation
1185
1179
  */
1186
- class RTEHtmlBlock extends codeBlock.RTEBlock {
1187
- constructor(id, htmlTag) {
1188
- super(id);
1189
- this.type = 'html-block';
1190
- this.children = [];
1191
- this.htmlTag = htmlTag;
1180
+ class InlineHtmlAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1181
+ constructor() {
1182
+ super(...arguments);
1183
+ this.customAttributeHandler = new CustomAttributeAnnotationHandler();
1184
+ this.customStyleAnnotationHandler = new CustomStyleAnnotationHandler();
1185
+ this.customClassAnnotationHandler = new CustomClassAnnotationHandler();
1192
1186
  }
1193
1187
  /**
1194
- * Converts a VegaRTEHtmlBlock to an RTEHtmlBlock.
1195
- *
1196
- * @param {VegaRTEHtmlBlock} block - The VegaRTEHtmlBlock to convert.
1197
- * @param {VegaRTETransformOptions} [options] - Optional transformation options.
1198
- * @returns {RTEHtmlBlock} The converted RTEHtmlBlock.
1188
+ * @inheritDoc
1199
1189
  */
1200
- static from(block, options) {
1201
- const htmlBlock = new RTEHtmlBlock(block.id, block.htmlTag);
1202
- const { annotations } = block;
1203
- if (annotations) {
1204
- super.convertAnnotationsToMap(htmlBlock.annotationMap, annotations);
1190
+ canHandle(targetDto, options) {
1191
+ return targetDto.name === 'RTETextNode' && options.autoMatchFormat === false;
1192
+ }
1193
+ /**
1194
+ * @inheritDoc
1195
+ */
1196
+ handle(element, parentAnnotations) {
1197
+ const canHandle = InlineHtmlAnnotationHandler.canHandleTags.includes(element.nodeName);
1198
+ if (canHandle) {
1199
+ const inlineHtml = this.generateInlineHtmlAnnotation(element, Object.assign({}, parentAnnotations));
1200
+ if (inlineHtml) {
1201
+ return { inlineHtml: inlineHtml };
1202
+ }
1205
1203
  }
1206
- htmlBlock.children = block.children
1207
- .map((child) => {
1208
- const BlockClass = codeBlock.RTEDTOClassManager.getRTEBlockClass(child.type);
1209
- if (BlockClass) {
1210
- const block = BlockClass.from(child, options);
1211
- block.parent = htmlBlock;
1212
- return block;
1213
- }
1214
- })
1215
- .filter(typeGuard.isNonNullable);
1216
- return htmlBlock;
1204
+ return {};
1217
1205
  }
1218
1206
  /**
1219
- * @inheritDoc
1207
+ * Generate inline html annotation.
1208
+ *
1209
+ * @param {HTMLElement} child - Current element.
1210
+ * @param {VegaRTETextAnnotations} annotations - Current annotations.
1211
+ * @returns {Nullable<VegaInlineHtmlSchema>} - Inline html annotation.
1220
1212
  */
1221
- clone() {
1222
- const clonedBlock = new RTEHtmlBlock(this.id, this.htmlTag);
1223
- clonedBlock.children = this.children.map((child) => child.clone());
1224
- clonedBlock.annotationMap = super.cloneAnnotations();
1225
- return clonedBlock;
1213
+ generateInlineHtmlAnnotation(child, annotations) {
1214
+ let { inlineHtml } = annotations;
1215
+ if (!codeBlock.RTETextNode.supportsHtmlTag(child.nodeName.toLowerCase()) ||
1216
+ (child.childNodes.length === 1 && child.childNodes[0].nodeType !== Node.TEXT_NODE)) {
1217
+ const childInlineHtmlNode = {
1218
+ htmlTag: child.nodeName.toLowerCase(),
1219
+ customAttribute: this.customAttributeHandler.handle(child).customAttribute,
1220
+ customStyle: this.customStyleAnnotationHandler.handle(child).customStyle,
1221
+ customClass: this.customClassAnnotationHandler.handle(child).customClass,
1222
+ };
1223
+ if (!inlineHtml) {
1224
+ inlineHtml = childInlineHtmlNode;
1225
+ }
1226
+ else {
1227
+ let lastChild = inlineHtml;
1228
+ while (lastChild.child &&
1229
+ child.parentNode &&
1230
+ lastChild.child.htmlTag === child.parentNode.nodeName.toLowerCase()) {
1231
+ lastChild = lastChild.child;
1232
+ }
1233
+ lastChild.child = childInlineHtmlNode;
1234
+ }
1235
+ }
1236
+ return inlineHtml ? Object.assign({}, inlineHtml) : null;
1237
+ }
1238
+ }
1239
+ InlineHtmlAnnotationHandler.canHandleTags = [
1240
+ 'A',
1241
+ 'ABBR',
1242
+ 'AUDIO',
1243
+ 'B',
1244
+ 'BDI',
1245
+ 'BDO',
1246
+ 'CITE',
1247
+ 'CODE',
1248
+ 'DEL',
1249
+ 'DFN',
1250
+ 'EMBED',
1251
+ 'EM',
1252
+ 'I',
1253
+ 'INS',
1254
+ 'KBD',
1255
+ 'MARK',
1256
+ 'METER',
1257
+ 'OUTPUT',
1258
+ 'PROGRESS',
1259
+ 'Q',
1260
+ 'S',
1261
+ 'SMALL',
1262
+ 'SPAN',
1263
+ 'STRONG',
1264
+ 'SUB',
1265
+ 'SUP',
1266
+ 'TIME',
1267
+ 'U',
1268
+ 'VAR',
1269
+ 'VIDEO',
1270
+ ];
1271
+
1272
+ /** Html element to annotations generator */
1273
+ class HtmlElementToAnnotationGenerator {
1274
+ constructor() {
1275
+ this.handlers = [
1276
+ new TextAlignAnnotationHandler(),
1277
+ new IndentAnnotationHandler(),
1278
+ new BoldAnnotationHandler(),
1279
+ new ItalicAnnotationHandler(),
1280
+ new UnderlineAnnotationHandler(),
1281
+ new StrikeThroughAnnotationHandler(),
1282
+ new ColorAnnotationHandler(),
1283
+ new LinkAnnotationHandler(),
1284
+ new CodeAnnotationHandler(),
1285
+ new ImageSizeAnnotationHandler(),
1286
+ new ImageAltAnnotationHandler(),
1287
+ new CustomAttributeAnnotationHandler(),
1288
+ new CustomClassAnnotationHandler(),
1289
+ new CustomStyleAnnotationHandler(),
1290
+ new LinkAnnotationHandler(),
1291
+ new TextStyleAnnotationHandler(),
1292
+ new InlineHtmlAnnotationHandler(),
1293
+ ];
1226
1294
  }
1227
1295
  /**
1228
- * @inheritDoc
1296
+ * The function generates annotations for a given target DTO and HTML element based on a set of
1297
+ * strategies.
1298
+ *
1299
+ * @typedef T class name of target DTO
1300
+ * @typedef V generated annotations type
1301
+ * @param {T} targetDto - Which DTO is the generated annotations to set.
1302
+ * @param {HTMLElement} element - Current html element.
1303
+ * @param {HtmlElementToAnnotationGenerateOptions} [options] - Options
1304
+ * @returns {V} Generated annotations.
1229
1305
  */
1230
- getLastNode() {
1231
- return this.children[this.children.length - 1].getLastNode();
1306
+ generate(targetDto, element, options = { autoMatchFormat: true }) {
1307
+ const isLinkElement = element.tagName === 'A';
1308
+ return this.handlers
1309
+ .filter((handler) => !options.autoMatchFormat && isLinkElement ? handler instanceof LinkAnnotationHandler : true)
1310
+ .filter((handler) => element.nodeType !== Node.TEXT_NODE &&
1311
+ handler.canHandle(targetDto, {
1312
+ skipCustomAnnotations: options.skipCustomAnnotations || isLinkElement,
1313
+ autoMatchFormat: options.autoMatchFormat,
1314
+ }))
1315
+ .reduce((annotations, handler) => {
1316
+ const result = handler.handle(element, options.parentAnnotations);
1317
+ return Object.assign(Object.assign({}, annotations), result);
1318
+ }, {});
1232
1319
  }
1320
+ }
1321
+ const htmlElementToAnnotationGenerator = new HtmlElementToAnnotationGenerator();
1322
+
1323
+ /**
1324
+ * Abstract class to define strategies for processing HTML elements
1325
+ */
1326
+ class ElementToDTOStrategy {
1233
1327
  /**
1234
- * @inheritDoc
1328
+ * Convert element style attributes to text annotations.
1329
+ *
1330
+ * @param {HTMLElement} element - Current html element.
1331
+ * @param {HtmlElementToAnnotationGenerateOptions} options - Options for generating annotations.
1332
+ * @returns {VegaRTEAnnotations} - Generated annotations.
1235
1333
  */
1236
- isNotEmpty() {
1237
- return this.children.length > 0;
1334
+ generateTextStyleAnnotations(element, options) {
1335
+ return htmlElementToAnnotationGenerator.generate(codeBlock.RTETextNode, element, options);
1336
+ }
1337
+ }
1338
+ /**
1339
+ * Class to represent the output of a strategy applied to HTML elements
1340
+ */
1341
+ class ElementToDTOStrategyOutput {
1342
+ constructor(currentStrategy, currentElements) {
1343
+ this.childrenOutput = [];
1344
+ this.currentStrategy = currentStrategy;
1345
+ this.currentElements = currentElements;
1238
1346
  }
1239
1347
  /**
1240
- * @inheritDoc
1348
+ * Set children output.
1349
+ *
1350
+ * @param {ElementToDTOStrategyOutput[]} childrenOutput - children outputs.
1241
1351
  */
1242
- toHtml() {
1243
- const BlockTag = this.htmlTag;
1244
- const attrStr = super.generateAttributeString();
1245
- return [
1246
- `<${BlockTag}${attrStr}>`,
1247
- this.children.map((block) => block.toHtml()).join(''),
1248
- `</${BlockTag}>`,
1249
- ].join('');
1352
+ setChildrenOutput(childrenOutput) {
1353
+ this.childrenOutput = childrenOutput;
1250
1354
  }
1251
1355
  /**
1252
- * @inheritDoc
1356
+ * Transform current output and children output to DTO
1357
+ *
1358
+ * @param {VegaRTETransformOptions} [options] - Options for transformation.
1359
+ * @returns {Nullable<RTEContentBlock>} - DTO.
1253
1360
  */
1254
- toJSON() {
1255
- return Object.assign(Object.assign({}, super.toJSON()), { id: this.id, type: this.type, htmlTag: this.htmlTag, children: this.children.map((child) => child.toJSON()) });
1361
+ toDto(options = { autoMatchFormat: true, skipCustomAnnotations: true }) {
1362
+ const currentBlock = this.currentStrategy.handle(this.currentElements, options);
1363
+ if (this.childrenOutput.length > 0 && currentBlock) {
1364
+ this.currentStrategy.appendChildBlocks(currentBlock, this.childrenOutput
1365
+ .map((childOutput) => childOutput.toDto(options))
1366
+ .filter(typeGuard.isNonNullable));
1367
+ }
1368
+ return currentBlock;
1256
1369
  }
1257
1370
  }
1258
1371
 
1259
1372
  /**
1260
- * Merge the two blocks node into first block if the two blocks nodes type is same(text node or image node)
1261
- *
1262
- * @example firstBlock.apply(new MergeTwoBlocksNodesAction(secondBlock))
1373
+ * Manager for registering and retrieving strategies that convert HTML elements to DTOs.
1263
1374
  */
1264
- class MergeTwoBlocksNodesAction extends codeBlock.ModifyContentAction {
1265
- constructor(blockNeedToBeMerged) {
1266
- super();
1267
- this.type = codeBlock.ModifyContentActionType.MERGE_TWO_BLOCKS_NODES;
1268
- this.blockNeedToBeMerged = blockNeedToBeMerged;
1375
+ class elementToDTOClassStrategyManager {
1376
+ constructor() {
1377
+ this.elementToBlockStrategies = [];
1378
+ this.elementToNodeStrategies = [];
1269
1379
  }
1270
- }
1271
-
1272
- /**
1273
- * Block delete text or decorator node strategy.
1274
- */
1275
- class BlockDeleteTextOrDecoratorNodeStrategy extends codeBlock.BlockDeleteNodeContentStrategy {
1276
1380
  /**
1277
- * @inheritDoc
1381
+ * Registers a element to block strategy for converting HTML elements to DTOs. The new strategy is added to the beginning of the list to give it higher priority.
1382
+ *
1383
+ * @param {ElementToDTOStrategy} strategy - The strategy to register.
1278
1384
  */
1279
- handleAction(action, target) {
1280
- const { startContainerNode } = action;
1281
- if (!startContainerNode.isContentEditable()) {
1282
- this.deleteDecoratorNodeContent(action, target);
1283
- }
1284
- else if (startContainerNode.isTextNode()) {
1285
- this.deleteTextNodeContent(action, target);
1286
- }
1287
- const parent = target.parent;
1288
- if (parent && target.isListItemBlock() && parent.children.length === 0) {
1289
- parent.parent.apply(new codeBlock.RemoveChildrenAction(parent));
1385
+ registerElementToBlockStrategy(strategy) {
1386
+ if (!this.hasDuplicateStrategy(strategy, this.elementToBlockStrategies)) {
1387
+ this.elementToBlockStrategies.unshift(strategy);
1290
1388
  }
1291
1389
  }
1292
1390
  /**
1293
- * Handle the delete text logic when press delete key.
1391
+ * Registers an element to node strategy for converting HTML elements to DTOs. The new strategy is added to the beginning of the list to give it higher priority.
1294
1392
  *
1295
- * @param {DeleteBlockContentAction} action - ModifyContentAction
1296
- * @param {RTETextBlock} target - Current text block
1393
+ * @param {ElementToDTOStrategy} strategy - The strategy to register.
1297
1394
  */
1298
- deleteTextNodeContent(action, target) {
1299
- const startContainerNode = action.startContainerNode;
1300
- const startOffset = action.startOffset;
1301
- if (startOffset !== 0 && !startContainerNode.isEmpty()) {
1302
- const newText = startContainerNode.text.slice(0, startOffset - 1) +
1303
- startContainerNode.text.slice(startOffset);
1304
- startContainerNode.apply(new codeBlock.UpdateTextAction(newText));
1305
- if (newText) {
1306
- action.previousNode = startContainerNode;
1307
- return;
1308
- }
1309
- else {
1310
- const previousNode = this.getPreviousNode(startContainerNode);
1311
- // Remove the last character will not delete paragraph, the paragraph will removed after press delete again
1312
- if ((previousNode && previousNode.parent === target && previousNode['text'] === '\n') ||
1313
- target.children.length === 1) {
1314
- action.previousNode = startContainerNode;
1315
- return;
1316
- }
1317
- else {
1318
- target.apply(new codeBlock.RemoveChildrenAction(startContainerNode));
1319
- action.previousNode = previousNode;
1320
- return;
1321
- }
1322
- }
1323
- }
1324
- else {
1325
- let previousNode = this.getPreviousNode(startContainerNode);
1326
- let nextNode = null;
1327
- if (target.children.length && previousNode && previousNode.parent !== target) {
1328
- if (startContainerNode.isEmpty()) {
1329
- target.apply(new codeBlock.RemoveChildrenAction(startContainerNode));
1330
- }
1331
- if (target.type === previousNode.parent.type) {
1332
- previousNode.parent.apply(new MergeTwoBlocksNodesAction(target));
1333
- }
1334
- }
1335
- else {
1336
- if (this.isContentFirstNode(startContainerNode) && startContainerNode.isEmpty()) {
1337
- nextNode = this.getNextNode(startContainerNode);
1338
- }
1339
- /**
1340
- * Remove line break
1341
- *
1342
- * @example caret at the first line
1343
- * \n
1344
- * test
1345
- */
1346
- if (startContainerNode.isEmpty()) {
1347
- target.apply(new codeBlock.RemoveChildrenAction(startContainerNode));
1348
- }
1349
- /**
1350
- * Remove line break
1351
- *
1352
- * @example caret at the begin of second line
1353
- * \n
1354
- * test
1355
- */
1356
- if (previousNode && previousNode.isTextNode() && previousNode.isEmpty()) {
1357
- const shouldRemoveNode = previousNode;
1358
- previousNode = this.getPreviousNode(previousNode);
1359
- shouldRemoveNode.parent.apply(new codeBlock.RemoveChildrenAction(shouldRemoveNode));
1360
- if (!previousNode) {
1361
- nextNode = startContainerNode;
1362
- }
1363
- }
1364
- }
1365
- //Remove the paragraph block if the content is empty
1366
- if (target.children.length === 0) {
1367
- target.parent.apply(new codeBlock.RemoveChildrenAction(target));
1368
- }
1369
- if (previousNode) {
1370
- action.previousNode = previousNode;
1371
- }
1372
- else if (nextNode) {
1373
- action.nextNode = nextNode;
1374
- }
1395
+ registerElementToNodeStrategy(strategy) {
1396
+ if (!this.hasDuplicateStrategy(strategy, this.elementToNodeStrategies)) {
1397
+ this.elementToNodeStrategies.unshift(strategy);
1375
1398
  }
1376
1399
  }
1377
1400
  /**
1378
- * Delete decorator node content
1401
+ * Retrieves all registered element to block strategies for converting HTML elements to DTOs.
1379
1402
  *
1380
- * @param {DeleteBlockContentAction} action - The delete block content action
1381
- * @param {RTEBlock} target - The target block
1403
+ * @returns {ElementToDTOStrategy[]} - A set of all registered element to block strategies.
1382
1404
  */
1383
- deleteDecoratorNodeContent(action, target) {
1384
- const startContainerNode = action.startContainerNode, startOffset = action.startOffset;
1385
- let previousNode = this.getPreviousNode(startContainerNode);
1386
- let nextNode = null;
1387
- if (startOffset !== 0) {
1388
- const parentBlock = target;
1389
- if (this.isContentFirstNode(startContainerNode)) {
1390
- nextNode = this.getNextNode(startContainerNode);
1391
- }
1392
- if (parentBlock.children.length === 1) {
1393
- parentBlock.parent.apply(new codeBlock.RemoveChildrenAction(parentBlock));
1394
- }
1395
- else {
1396
- parentBlock.apply(new codeBlock.RemoveChildrenAction(startContainerNode));
1397
- }
1398
- }
1399
- else {
1400
- const shouldRemoveNode = previousNode;
1401
- if (shouldRemoveNode && !shouldRemoveNode.isContentEditable()) {
1402
- previousNode = this.getPreviousNode(shouldRemoveNode);
1403
- shouldRemoveNode.parent.apply(new codeBlock.RemoveChildrenAction(shouldRemoveNode));
1404
- if (!previousNode) {
1405
- action.nextNode = startContainerNode;
1406
- }
1407
- }
1408
- }
1409
- if (previousNode) {
1410
- action.previousNode = previousNode;
1411
- }
1412
- else if (nextNode) {
1413
- action.nextNode = nextNode;
1414
- }
1405
+ getElementToBlockStrategies() {
1406
+ return this.elementToBlockStrategies;
1415
1407
  }
1416
- }
1417
-
1418
- /**
1419
- * Insert new paragraph into current block at special position.
1420
- */
1421
- class BlockInsertNewParagraphStrategy extends codeBlock.ActionHandleStrategy {
1422
1408
  /**
1423
- * @inheritDoc
1409
+ * Retrieves all registered element to node strategies for converting HTML elements to DTOs.
1410
+ *
1411
+ * @returns {ElementToDTOStrategy[]} - A set of all registered element to node strategies.
1424
1412
  */
1425
- handleAction(action, target) {
1426
- const { startContainerNode } = action;
1427
- action.newBlock = this.breakSingleBlock(startContainerNode, action.startOffset, target);
1413
+ getElementToNodeStrategies() {
1414
+ return this.elementToNodeStrategies;
1428
1415
  }
1429
1416
  /**
1430
- * breakSingleTextBlock
1417
+ * Checks if a strategy is already registered in the provided strategy list.
1431
1418
  *
1432
- * @param {RTETextNode} splitNode -
1433
- * @param {number} startOffsetOfNode -
1434
- * @param {RTEBlock} target -
1435
- * @returns {Nullable<RTEBlock>} Nullable<RTEBlock>
1419
+ * @param {ElementToDTOStrategy} strategy - The strategy to check for duplicates.
1420
+ * @param {ElementToDTOStrategy[]} strategyList - The list of strategies to check against.
1421
+ * @returns {boolean} - True if the strategy is a duplicate, false otherwise.
1436
1422
  */
1437
- breakSingleBlock(splitNode, startOffsetOfNode, target) {
1438
- const newParagraph = this.getNewParagraph(splitNode);
1439
- if (newParagraph) {
1440
- if (this.isCaretPositionAtBlockEnd(target, splitNode, startOffsetOfNode)) {
1441
- target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newParagraph));
1442
- }
1443
- else if (this.isCaretPositionAtBlockStart(target, splitNode, startOffsetOfNode)) {
1444
- target.parent.apply(new codeBlock.InsertChildrenBeforeAction(target, newParagraph));
1423
+ hasDuplicateStrategy(strategy, strategyList) {
1424
+ return strategyList.includes(strategy);
1425
+ }
1426
+ }
1427
+ const ElementToDTOClassStrategyManager = new elementToDTOClassStrategyManager();
1428
+
1429
+ /** Element to DTO processor */
1430
+ class ElementToDtoStrategyProcessor {
1431
+ /**
1432
+ * Transform process.
1433
+ *
1434
+ * @param {HTMLElement[]} elements - Current elements.
1435
+ * @param {VegaRTETransformOptions} [options] - Options for transformation.
1436
+ * @returns {ElementToDTOStrategyOutput[]} - outputs.
1437
+ */
1438
+ process(elements, options = { autoMatchFormat: true, skipCustomAnnotations: true }) {
1439
+ const strategies = this.getElementToBlockStrategies();
1440
+ const outputs = [];
1441
+ for (let i = 0; i < elements.length; i++) {
1442
+ if (this.isInvalidElement(elements[i]))
1443
+ continue;
1444
+ let canHandledCount = 0;
1445
+ for (const strategy of strategies) {
1446
+ canHandledCount = strategy.canHandle(elements, i, options);
1447
+ if (canHandledCount > 0) {
1448
+ const handledElements = elements.slice(i, i + canHandledCount);
1449
+ const output = new ElementToDTOStrategyOutput(strategy, handledElements);
1450
+ if (canHandledCount === 1 && strategy.shouldProceedToElementChildren()) {
1451
+ output.setChildrenOutput(this.process(Array.from(handledElements[0].childNodes), options));
1452
+ }
1453
+ outputs.push(output);
1454
+ i += canHandledCount - 1;
1455
+ break;
1456
+ }
1445
1457
  }
1446
- else {
1447
- const splitBlockAction = new codeBlock.SplitBlockWithNodeAction(splitNode, startOffsetOfNode);
1448
- target.apply(splitBlockAction);
1449
- return splitBlockAction.newBlock;
1458
+ if (canHandledCount === 0 && i < elements.length) {
1459
+ const elementChildren = Array.from(elements[i].childNodes);
1460
+ const childrenOutputs = this.process(Array.from(elementChildren), options);
1461
+ if (childrenOutputs.length > 0) {
1462
+ outputs.push(...childrenOutputs);
1463
+ }
1450
1464
  }
1451
- return newParagraph;
1452
1465
  }
1466
+ return outputs;
1453
1467
  }
1454
1468
  /**
1455
- * Create new Paragraph
1469
+ * Checks if the given element is valid to parse.
1456
1470
  *
1457
- * @param {RTENode} splitNode - The split node of the block.
1458
- * @returns {Nullable<RTETextBlock>} - The new text block.
1471
+ * @param {HTMLElement} element - The pasted element.
1472
+ * @returns {boolean} Is valid
1459
1473
  */
1460
- getNewParagraph(splitNode) {
1461
- const newParagraph = this.createNewParagraph('');
1462
- if (newParagraph) {
1463
- let textNode = newParagraph.children[0];
1464
- if (splitNode.isTextNode() && splitNode.isContentEditable()) {
1465
- newParagraph.children = [];
1466
- textNode = splitNode.cloneWithText('');
1467
- // The link annotation don't need inherited
1468
- textNode.annotationMap.delete(codeBlock.NodeAnnotationTypeEnum.LINK);
1469
- newParagraph.apply(new codeBlock.AppendChildrenAction([textNode]));
1470
- }
1471
- return newParagraph;
1472
- }
1474
+ isInvalidElement(element) {
1475
+ if (element.nodeType === Node.COMMENT_NODE)
1476
+ return true;
1477
+ return ['META', 'STYLE'].includes(element.nodeName);
1478
+ }
1479
+ /**
1480
+ * Get the register element to block strategies.
1481
+ *
1482
+ * @returns {ElementToDTOStrategy[]} - The register element to block strategies.
1483
+ */
1484
+ getElementToBlockStrategies() {
1485
+ return ElementToDTOClassStrategyManager.getElementToBlockStrategies();
1473
1486
  }
1474
1487
  }
1488
+ const ElementToDtoStrategyProcessor$1 = new ElementToDtoStrategyProcessor();
1475
1489
 
1476
1490
  /**
1477
1491
  * Update the cursor position in the editor.
1478
- *
1479
- * @example richEditorRef.value.apply(new UpdateCursorPositionAction(nextFocusNode, [offset]))
1480
1492
  */
1481
- class UpdateCursorPositionAction extends codeBlock.ModifyContentAction {
1493
+ class UpdateCursorPositionStrategy extends codeBlock.ActionHandleStrategy {
1482
1494
  /**
1483
- * Set the cursor position at end of the current node.
1484
- *
1485
- * @param {RTENode} nextFocusNode - The rich text editor needs focus node.
1486
- * @param {number} offset - The cursor offset position.
1495
+ * @inheritDoc
1487
1496
  */
1488
- constructor(nextFocusNode, offset) {
1489
- super();
1490
- this.type = codeBlock.ModifyContentActionType.UPDATE_CURSOR_POSITION;
1491
- this.nextFocusNode = nextFocusNode;
1492
- this.offset = offset;
1497
+ handleAction(action, target) {
1498
+ const { offset, nextFocusNode, immediatelyRun } = action;
1499
+ const host = codeBlock.stateEntityRenderingRegistry.getDOMByEntity(target);
1500
+ if (host) {
1501
+ changeManager.ChangeManager.notify(domNodeSubjectObserverFactory.domNodeSubjectFactory.getSubject(host, vegaInternalEventId.VegaInternalUpdateRTECursorPosition), {
1502
+ node: nextFocusNode,
1503
+ offset,
1504
+ updateDirectly: immediatelyRun,
1505
+ });
1506
+ }
1507
+ }
1508
+ }
1509
+
1510
+ /**
1511
+ * Append new block array or node array to block or VegaRTEContent instance strategy.
1512
+ */
1513
+ class AppendChildrenStrategy extends codeBlock.ActionHandleStrategy {
1514
+ /**
1515
+ * @inheritDoc
1516
+ */
1517
+ handleAction(action, target) {
1518
+ const newBlocks = action.entityToBeAppended;
1519
+ if (target.children) {
1520
+ newBlocks.forEach((block) => {
1521
+ block.parent = target;
1522
+ });
1523
+ // This line is used to fix the typescript error `This expression is not callable`. https://github.com/microsoft/TypeScript/issues/44373
1524
+ const arrayFixed = target.children;
1525
+ target.children = arrayFixed.concat(newBlocks);
1526
+ }
1493
1527
  }
1494
1528
  }
1495
1529
 
1496
1530
  /**
1497
- * Strategy for inserting text into a decorator node. The decorator can not edit, so we insert the text as a new child.
1531
+ * Insert children at the front of the block strategy.
1498
1532
  */
1499
- class InsertTextToDecoratorNodeStrategy extends codeBlock.ActionHandleStrategy {
1533
+ class InsertChildrenBeforeStrategy extends codeBlock.ActionHandleStrategy {
1500
1534
  /**
1501
1535
  * @inheritDoc
1502
1536
  */
1503
1537
  handleAction(action, target) {
1504
- const { text, offset, decoratorNode } = action;
1505
- const paragraph = this.createNewParagraph(text);
1506
- if (paragraph) {
1507
- const newTextNode = paragraph.children[0];
1508
- if (offset !== 0) {
1509
- target.apply(new codeBlock.InsertChildrenAfterAction(decoratorNode, newTextNode));
1510
- }
1511
- else {
1512
- target.apply(new codeBlock.InsertChildrenBeforeAction(decoratorNode, newTextNode));
1513
- }
1514
- this.setTheCursorPosition(newTextNode);
1515
- }
1538
+ this.replaceElementWithElements(target, action.referChildren, [
1539
+ ...action.childrenToBeInserted,
1540
+ action.referChildren,
1541
+ ]);
1516
1542
  }
1517
1543
  /**
1518
- * Set the cursor position to the new text node.
1544
+ * Replaces a specific block or node with an array of blocks or nodes within RTEContentBlock array.
1519
1545
  *
1520
- * @param {RTENode} focusNode - The new text node to focus on.
1546
+ * @param {RTEBlock | VegaRTEContent} target - The block or the VegaRTEContent instance.
1547
+ * @param {RTEBlock | RTENode} referElement - Used as a reference element to identify the element that needs to be replaced in the array.
1548
+ * @param {RTEBlock[] | RTENode[]} elements - An array of block or node objects that you want to replace the `referElement` with in the array.
1521
1549
  */
1522
- setTheCursorPosition(focusNode) {
1523
- const rootContent = this.getRootContent(focusNode.parent);
1524
- if (rootContent) {
1525
- rootContent.apply(new UpdateCursorPositionAction(focusNode));
1550
+ replaceElementWithElements(target, referElement, elements) {
1551
+ if (target.children) {
1552
+ elements.forEach((block) => {
1553
+ block.parent = target;
1554
+ });
1555
+ const arrayFixed = target.children;
1556
+ target.children = arrayFixed.flatMap((block) => {
1557
+ if (block === referElement) {
1558
+ return elements;
1559
+ }
1560
+ else {
1561
+ return block;
1562
+ }
1563
+ });
1526
1564
  }
1527
1565
  }
1528
1566
  }
1529
1567
 
1530
1568
  /**
1531
- * Insert new paragraph into current list item block at special position.
1569
+ * Insert children at the front of the block strategy.
1532
1570
  */
1533
- class ListItemInsertNewParagraphStrategy extends codeBlock.ActionHandleStrategy {
1571
+ class InsertChildrenAfterStrategy extends InsertChildrenBeforeStrategy {
1534
1572
  /**
1535
1573
  * @inheritDoc
1536
1574
  */
1537
1575
  handleAction(action, target) {
1538
- action.newBlock = this.breakSingleListItemBlock(action.startContainerNode, action.startOffset, target);
1576
+ this.replaceElementWithElements(target, action.referChildren, [
1577
+ action.referChildren,
1578
+ ...action.childrenToBeInserted,
1579
+ ]);
1580
+ }
1581
+ }
1582
+
1583
+ /**
1584
+ * Annotation for image
1585
+ */
1586
+ class ImageAnnotation extends codeBlock.NodeAnnotation {
1587
+ constructor(size, alt) {
1588
+ super();
1589
+ this.type = codeBlock.NodeAnnotationTypeEnum.IMAGE;
1590
+ this.size = size;
1591
+ this.alt = alt;
1539
1592
  }
1540
1593
  /**
1541
- * Breaks a single list item block at a specific position.
1594
+ * Generate the map item for the annotation
1542
1595
  *
1543
- * @param {RTETextNode} splitNode - The node that needs to be split within a list item block.
1544
- * @param {number} startOffsetOfNode - The index within the `splitNode` where the break operation should occur.
1545
- * @param {RTEListItemBlock} target - The list item block.
1546
- * @returns {Nullable<RTEBlock>} Returns either a new `RTEListItemBlock` if the caret
1547
- * position is at the end of the `splitNode`, or it returns the result of splitting the block at the
1548
- * caret position if it is neither at the start nor at the end.
1596
+ * @param {string} size - Image size
1597
+ * @param {string} alt - Image alt
1598
+ * @returns {[NodeAnnotationTypeEnum.IMAGE, ImageAnnotation]} Map item for the annotation
1549
1599
  */
1550
- breakSingleListItemBlock(splitNode, startOffsetOfNode, target) {
1551
- const newListItem = target.createNewListItem();
1552
- const newBreakNode = this.copyInlineStyleToNewNode(splitNode);
1553
- newListItem.apply(new codeBlock.AppendChildrenAction([newBreakNode]));
1554
- if (this.isCaretPositionAtBlockEnd(target, splitNode, startOffsetOfNode)) {
1555
- return this.breakListItemAtEnd(newListItem, target);
1556
- }
1557
- else if (this.isCaretPositionAtBlockStart(target, splitNode, startOffsetOfNode)) {
1558
- target.parent.apply(new codeBlock.InsertChildrenBeforeAction(target, newListItem));
1559
- }
1560
- else {
1561
- const splitBlockAction = new codeBlock.SplitBlockWithNodeAction(splitNode, startOffsetOfNode);
1562
- target.apply(splitBlockAction);
1563
- return splitBlockAction.newBlock;
1564
- }
1565
- return newListItem;
1600
+ static from(size, alt) {
1601
+ return [codeBlock.NodeAnnotationTypeEnum.IMAGE, new ImageAnnotation(size, alt)];
1566
1602
  }
1567
1603
  /**
1568
- * Breaks a list item at the end and handles the insertion of a new list item or paragraph accordingly.
1604
+ * Generate the JSON representation of the annotation
1569
1605
  *
1570
- * @param {RTEListItemBlock} newListItem - Item that represents a new list item to be added to the existing list.
1571
- * @param {RTEListItemBlock} target - The list item block.
1572
- * @returns {RTEBlock} Returns a `RTEBlock`.
1606
+ * @returns {Nullable<Record<string, unknown>>} JSON representation of the annotation
1573
1607
  */
1574
- breakListItemAtEnd(newListItem, target) {
1575
- const lastItem = target.parent.children[target.parent.children.length - 1];
1576
- const currentItemIsEmpty = target.children.length === 1 && target.children[0].isEmpty();
1577
- if (target === lastItem && currentItemIsEmpty) {
1578
- const parentParent = target.parent.parent;
1579
- if (parentParent['type'] !== 'list-item') {
1580
- const newParagraph = codeBlock.RTETextBlock.from({
1581
- id: createPublicApiRuntimeMetricsSlimmer.generateUUID(),
1582
- type: 'paragraph',
1583
- nodes: [],
1584
- });
1585
- newParagraph.apply(new codeBlock.AppendChildrenAction(newListItem.children));
1586
- parentParent.apply(new codeBlock.InsertChildrenAfterAction(target.parent, newParagraph));
1587
- target.parent.apply(new codeBlock.RemoveChildrenAction(target));
1588
- return newParagraph;
1589
- }
1590
- else {
1591
- parentParent.parent.apply(new codeBlock.InsertChildrenAfterAction(parentParent, newListItem));
1592
- target.parent.apply(new codeBlock.RemoveChildrenAction(target));
1608
+ toJSON() {
1609
+ return typeGuard.isNonNullable(this.alt)
1610
+ ? {
1611
+ size: this.size,
1612
+ alt: this.alt,
1593
1613
  }
1594
- }
1595
- else {
1596
- target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newListItem));
1597
- }
1598
- return newListItem;
1614
+ : {
1615
+ size: this.size,
1616
+ };
1599
1617
  }
1600
1618
  /**
1601
- * Copy the inline style to new node
1602
- *
1603
- * @param {RTETextNode} needCopedNode - The node that needed to be copied to
1604
- * @returns {RTETextNode} Returns a `RTETextNode`.
1619
+ * @inheritDoc
1605
1620
  */
1606
- copyInlineStyleToNewNode(needCopedNode) {
1607
- const textNode = needCopedNode.cloneWithText('');
1608
- // The link annotation doesn't need to inherit
1609
- textNode.annotationMap.delete(codeBlock.NodeAnnotationTypeEnum.LINK);
1610
- return textNode;
1621
+ clone() {
1622
+ return new ImageAnnotation(this.size, this.alt);
1611
1623
  }
1612
- }
1613
-
1614
- /**
1615
- * Delete the nest list block action
1616
- *
1617
- * @example needRemovedNestList.parent.apply(new RemoveNestListAction(needRemovedNestList))
1618
- */
1619
- class RemoveNestListAction extends codeBlock.ModifyContentAction {
1620
- constructor(childList) {
1621
- super();
1622
- this.type = codeBlock.ModifyContentActionType.DELETE_NEST_LIST;
1623
- this.nestListBlockToBeRemoved = childList;
1624
+ /**
1625
+ * @inheritDoc
1626
+ */
1627
+ renderClass(options) {
1628
+ if (options === null || options === void 0 ? void 0 : options.standalone)
1629
+ return null;
1630
+ return this.size ? `v-rte--image-size-${this.size}` : null;
1624
1631
  }
1625
- }
1626
-
1627
- /**
1628
- * List remove list item strategy.
1629
- */
1630
- class ListRemoveListItemStrategy extends codeBlock.RemoveChildrenStrategy {
1631
1632
  /**
1632
- * Remove the list item, check the list item and remove self if the list item is empty.
1633
- *
1634
- * @param {RemoveChildrenAction} action - The remove action instance.
1635
- * @param {RTEListBlock} target - The list block.
1633
+ * @inheritDoc
1636
1634
  */
1637
- handleAction(action, target) {
1638
- super.handleAction(action, target);
1639
- const parent = target.parent;
1640
- if (target.children.length === 0 && parent) {
1641
- // The parent is a list item mean the current block is a nest list, so we need to use RemoveNestListAction to remove the item
1642
- if (parent['type'] === 'list-item') {
1643
- parent.apply(new RemoveNestListAction(target));
1635
+ renderStyle(options) {
1636
+ if (!(options === null || options === void 0 ? void 0 : options.standalone))
1637
+ return null;
1638
+ const baseStyle = { verticalAlign: 'bottom' };
1639
+ switch (this.size) {
1640
+ case 'sm': {
1641
+ return Object.assign(Object.assign({}, baseStyle), { width: '25%' });
1644
1642
  }
1645
- else {
1646
- parent.apply(new codeBlock.RemoveChildrenAction(target));
1643
+ case 'md': {
1644
+ return Object.assign(Object.assign({}, baseStyle), { width: '50%' });
1645
+ }
1646
+ case 'lg': {
1647
+ return Object.assign(Object.assign({}, baseStyle), { width: '100%' });
1647
1648
  }
1648
1649
  }
1649
1650
  }
1650
1651
  }
1651
1652
 
1652
1653
  /**
1653
- * Manager class for registering DTO action strategies.
1654
+ * Update the image node annotation map strategy.
1654
1655
  */
1655
- class RTEDTOActionStrategyManager {
1656
+ class ImageSetAnnotationMapStrategy extends codeBlock.ActionHandleStrategy {
1656
1657
  /**
1657
- * Registers basic strategies for a given DTO class.
1658
- *
1659
- * @param {string} dtoClassName - The name of the RTE block class name.
1658
+ * @inheritDoc
1660
1659
  */
1661
- registerBlockBasicStrategies(dtoClassName) {
1662
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.DELETE_CHILDREN, dtoClassName, dtoClassName === RTEListBlock.name
1663
- ? new ListRemoveListItemStrategy()
1664
- : new codeBlock.RemoveChildrenStrategy());
1665
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.APPEND_CHILDREN, dtoClassName, new AppendChildrenStrategy());
1666
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_CHILDREN_BEFORE, dtoClassName, new InsertChildrenBeforeStrategy());
1667
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_CHILDREN_AFTER, dtoClassName, new InsertChildrenAfterStrategy());
1668
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.DELETE_BLOCK_CONTENT, dtoClassName, new BlockDeleteTextOrDecoratorNodeStrategy());
1669
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_NEW_PARAGRAPH, dtoClassName, dtoClassName === RTEListItemBlock.name
1670
- ? new ListItemInsertNewParagraphStrategy()
1671
- : new BlockInsertNewParagraphStrategy());
1672
- codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_TEXT_TO_DECORATOR_NODE, dtoClassName, new InsertTextToDecoratorNodeStrategy());
1660
+ handleAction(action, target) {
1661
+ const annotation = action.toAnnotation();
1662
+ target.annotationMap.set(annotation.type, annotation);
1673
1663
  }
1674
1664
  }
1675
- const RTEDTOActionStrategyManager$1 = new RTEDTOActionStrategyManager();
1676
1665
 
1677
1666
  /**
1678
- * Abstract class to define handler for generate the annotations
1667
+ * The image node update property url strategy.
1679
1668
  */
1680
- class AnnotationGeneratorStrategyAbstract {
1681
- }
1682
-
1683
- /** Handle bold annotation */
1684
- class BoldAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1669
+ class ImageUpdateUrlStrategy extends codeBlock.ActionHandleStrategy {
1685
1670
  /**
1686
1671
  * @inheritDoc
1687
1672
  */
1688
- canHandle(targetDto) {
1689
- return targetDto.name === 'RTETextNode';
1673
+ handleAction(action, target) {
1674
+ target.url = action.url;
1675
+ }
1676
+ }
1677
+
1678
+ var __rest = (undefined && undefined.__rest) || function (s, e) {
1679
+ var t = {};
1680
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
1681
+ t[p] = s[p];
1682
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
1683
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
1684
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
1685
+ t[p[i]] = s[p[i]];
1686
+ }
1687
+ return t;
1688
+ };
1689
+ /**
1690
+ * Image node
1691
+ */
1692
+ class RTEImageNode extends codeBlock.RTEDecoratorNode {
1693
+ constructor(id, url, parentBlock, annotationMap) {
1694
+ super(id, annotationMap);
1695
+ this.type = codeBlock.NodeTypeEnum.IMAGE;
1696
+ this.url = url;
1697
+ this.parent = parentBlock;
1690
1698
  }
1691
1699
  /**
1692
- * Handle annotation.
1700
+ * Converts a VegaRTEImageNode into an RTEImageNode by mapping nodes and creating annotations.
1693
1701
  *
1694
- * @param {HTMLElement} element - Current elements.
1695
- * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
1696
- * @returns {VegaRTETextAnnotations} - Annotation.
1702
+ * @param {VegaRTEImageNode} node - The node to be converted.
1703
+ * @param {RTEImageBlock} parentBlock - The parent block
1704
+ * @param {VegaRTETransformOptions} options - Optional transformation options.
1705
+ * @returns {RTEImageNode} An instance of `RTEImageBlock`
1697
1706
  */
1698
- handle(element, parentAnnotations = {}) {
1699
- return this.isBold(element) || parentAnnotations.bold ? { bold: true } : {};
1707
+ static from(node, parentBlock, options = { autoMatchFormat: true }) {
1708
+ const imageNode = new RTEImageNode(node.id, node.url, parentBlock);
1709
+ const autoMatchFormat = !!options.autoMatchFormat;
1710
+ const _a = Object.assign({}, node.annotations), { size } = _a, otherAnnotations = __rest(_a, ["size"]);
1711
+ const annotations = Object.assign(Object.assign({}, otherAnnotations), { size: size !== null && size !== void 0 ? size : (autoMatchFormat ? 'md' : undefined) });
1712
+ imageNode.annotationMap = new Map(Object.keys(annotations)
1713
+ .map((type) => {
1714
+ if (type === 'size' || type === 'alt') {
1715
+ return ImageAnnotation.from(annotations.size, annotations.alt);
1716
+ }
1717
+ return this.createAnnotationEntity(type, annotations[type]);
1718
+ })
1719
+ .filter(typeGuard.isNonNullable));
1720
+ return imageNode;
1700
1721
  }
1701
1722
  /**
1702
- * Is bold element.
1703
- *
1704
- * @param {HTMLElement} element - current element.
1705
- * @returns {boolean} - boolean.
1723
+ * @inheritDoc
1706
1724
  */
1707
- isBold(element) {
1708
- return (element.nodeName === 'STRONG' ||
1709
- element.nodeName === 'B' ||
1710
- element.style.fontWeight === 'bold' ||
1711
- element.style.fontWeight === '700' ||
1712
- element.classList.contains('v-rte--bold'));
1725
+ toJSON() {
1726
+ const annotations = Array.from(this.annotationMap.values())
1727
+ .filter((annotation) => annotation instanceof ImageAnnotation || annotation instanceof codeBlock.CommonAnnotation)
1728
+ .reduce((record, annotation) => {
1729
+ return Object.assign(Object.assign({}, record), annotation.toJSON());
1730
+ }, {});
1731
+ if (annotations.alt == '')
1732
+ delete annotations.alt;
1733
+ return Object.assign(Object.assign({ id: this.id }, (Object.keys(annotations).length > 0 ? { annotations } : {})), { type: 'image', url: this.url });
1713
1734
  }
1714
- }
1715
-
1716
- /** Handle custom attribute annotation */
1717
- class CustomAttributeAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1718
1735
  /**
1719
- * Can be handle.
1720
- *
1721
- * @param {RTEDtoClassPrototype} targetDto - Target DTO.
1722
- * @param {HtmlElementToAnnotationGenerateOptions} [options] - Options for annotation generator.
1723
- * @returns {boolean} - .
1736
+ * @inheritDoc
1724
1737
  */
1725
- canHandle(targetDto, options) {
1726
- return !options.skipCustomAnnotations && !!targetDto;
1738
+ clone() {
1739
+ return new RTEImageNode(this.id, this.url, this.parent, super.cloneAnnotations());
1727
1740
  }
1728
1741
  /**
1729
- * Handle annotation.
1730
- *
1731
- * @param {HTMLElement} element - Current elements.
1732
- * @returns {VegaRTETextAnnotations} - Annotation.
1742
+ * @inheritDoc
1733
1743
  */
1734
- handle(element) {
1735
- const attributes = this.getAttributes(element);
1736
- return Object.keys(attributes).length > 0 ? { customAttribute: attributes } : {};
1744
+ toHtml() {
1745
+ const imageAnnotation = this.getAnnotationByType(codeBlock.NodeAnnotationTypeEnum.IMAGE);
1746
+ const attrStr = super.generateAttributeString(...[
1747
+ imageAnnotation && imageAnnotation.alt ? `alt="${imageAnnotation.alt}"` : null,
1748
+ `src="${this.url}"`,
1749
+ imageAnnotation && imageAnnotation.size ? `data-size="${imageAnnotation.size}"` : null,
1750
+ ].filter(typeGuard.isNonNullable));
1751
+ return `<img${attrStr}>`;
1737
1752
  }
1738
1753
  /**
1739
- * Obtain the custom attributes of element, excluding 'style' and 'class'.
1740
- *
1741
- * @param {HTMLElement} element - current element.
1742
- * @returns {Record<string, string>} - Record<string, string>.
1754
+ * @inheritDoc
1743
1755
  */
1744
- getAttributes(element) {
1745
- const attributeNames = element
1746
- .getAttributeNames()
1747
- .filter((attr) => attr !== 'style' && attr !== 'class' && this.isValidAttr(attr));
1748
- return attributeNames.reduce((acc, item) => {
1749
- acc[item] = element.getAttribute(item);
1750
- return acc;
1751
- }, {});
1756
+ doAnnotationActionApply(action) {
1757
+ const strategy = codeBlock.ActionHandleStrategyRegistry.get(codeBlock.AnnotationAction.name, RTEImageNode.name);
1758
+ if (strategy) {
1759
+ strategy.execute(action, this);
1760
+ }
1752
1761
  }
1753
1762
  /**
1754
- * Check if the attribute name is valid.
1755
- *
1756
- * @param {string} attr - Attribute name.
1757
- * @returns {boolean} - True if valid, false otherwise.
1763
+ * @inheritDoc
1758
1764
  */
1759
- isValidAttr(attr) {
1760
- return /^[a-zA-Z_][\w-]*$/.test(attr);
1765
+ doModifyActionApply(action) {
1766
+ codeBlock.ActionHandleStrategyRegistry.executeTheStrategy(action, this);
1761
1767
  }
1762
1768
  }
1769
+ (() => {
1770
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.UPDATE_IMAGE_NODE_URL, RTEImageNode.name, new ImageUpdateUrlStrategy());
1771
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.AnnotationAction.name, RTEImageNode.name, new ImageSetAnnotationMapStrategy());
1772
+ })();
1763
1773
 
1764
- /** Handle custom class annotation */
1765
- class CustomClassAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1774
+ /**
1775
+ * Split the current image block with a special position strategy.
1776
+ */
1777
+ class BlockSplitWithImageNodeStrategy extends codeBlock.ActionHandleStrategy {
1766
1778
  /**
1767
- * Can be handle.
1768
- *
1769
- * @param {RTEDtoClassPrototype} targetDto - Target DTO.
1770
- * @param {HtmlElementToAnnotationGenerateOptions} [options] - Options for annotation generator.
1771
- * @returns {boolean} - .
1779
+ * @inheritDoc
1772
1780
  */
1773
- canHandle(targetDto, options) {
1774
- return !options.skipCustomAnnotations && !!targetDto;
1781
+ handleAction(action, target) {
1782
+ action.newBlock = this.splitImageNodes(action.splitPointNode, action.startOffsetOfNode, target);
1775
1783
  }
1776
1784
  /**
1777
- * Handle annotation.
1785
+ * The image offset should be 0 or 1
1786
+ * <vega-rich-text-image-editor><img /></vega-rich-text-image-editor>
1778
1787
  *
1779
- * @param {HTMLElement} element - Current elements.
1780
- * @returns {VegaRTETextAnnotations} - Annotation.
1788
+ * @param {RTEImageNode} imageNode The split point image node.
1789
+ * @param {number} imageOffset The cursor point 0 | 1.
1790
+ * @param {RTEImageBlock} target The image block.
1791
+ * @returns {Nullable<RTEBlock>} The new block after split
1781
1792
  */
1782
- handle(element) {
1783
- const classes = this.getCustomClass(element);
1784
- return classes.length > 0 ? { customClass: classes } : {};
1793
+ splitImageNodes(imageNode, imageOffset, target) {
1794
+ const nodesSplitIndex = target.children.indexOf(imageNode);
1795
+ if (nodesSplitIndex > -1) {
1796
+ const beforeNodes = target.children.slice(0, nodesSplitIndex + imageOffset);
1797
+ const afterNodes = target.children.slice(nodesSplitIndex + imageOffset);
1798
+ target.apply(new codeBlock.ReplaceChildNodesAction(beforeNodes));
1799
+ const newBlock = this.cloneWithNodes(afterNodes, target);
1800
+ target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newBlock));
1801
+ return newBlock;
1802
+ }
1785
1803
  }
1786
1804
  /**
1787
- * Get the custom class
1805
+ * Creates a new RTEImageBlock instance with the provided RTEImageNode instances appended to it.
1788
1806
  *
1789
- * @param {HTMLElement} element - current element.
1790
- * @returns {string[]} - the class after .
1807
+ * @param {RTEImageNode[]} nodes - An array of RTEImageNode objects that will be used to create a new RTEImageBlock instance.
1808
+ * @param {RTEImageBlock} target The image block.
1809
+ * @returns {RTEImageBlock} A new `RTEImageBlock` object with the provided `nodes` appended to it.
1791
1810
  */
1792
- getCustomClass(element) {
1793
- return element.classList
1794
- .toString()
1795
- .split(' ')
1796
- .filter((item) => !item.includes('v-rte') && item !== '');
1811
+ cloneWithNodes(nodes, target) {
1812
+ const block = target.createNewImageBlock();
1813
+ block.children = [];
1814
+ block.apply(new codeBlock.AppendChildrenAction(nodes));
1815
+ return block;
1797
1816
  }
1798
1817
  }
1799
1818
 
1800
- /** Handle custom style annotation */
1801
- class CustomStyleAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1802
- /**
1803
- * Can be handle.
1804
- *
1805
- * @param {RTEDtoClassPrototype} targetDto - Target DTO.
1806
- * @param {HtmlElementToAnnotationGenerateOptions} [options] - Options for annotation generator.
1807
- * @returns {boolean} - .
1808
- */
1809
- canHandle(targetDto, options) {
1810
- return !options.skipCustomAnnotations && !!targetDto;
1811
- }
1812
- /**
1813
- * Handle annotation.
1814
- *
1815
- * @param {HTMLElement} element - Current elements.
1816
- * @returns {VegaRTETextAnnotations} - Annotation.
1817
- */
1818
- handle(element) {
1819
- const styles = this.generateCustomStyleAnnotations(element);
1820
- return Object.keys(styles).length > 0 ? { customStyle: styles } : {};
1819
+ /**
1820
+ * Break the current block after press enter, this action is similar with the SplitBlockWithNodeAction,
1821
+ * The SplitBlockWithNodeAction split the current block to two same type blocks, but this action will create new paragraph or list item when break at start or end.
1822
+ * The property `newBlock` use to store the new create block if need.
1823
+ *
1824
+ * @example currentBlock.apply(new InsertNewParagraphAction(startContainerNode, startOffset))
1825
+ */
1826
+ class InsertNewParagraphAction extends codeBlock.ModifyContentAction {
1827
+ constructor(startContainerNode, startOffset) {
1828
+ super();
1829
+ this.type = codeBlock.ModifyContentActionType.INSERT_NEW_PARAGRAPH;
1830
+ this.startContainerNode = startContainerNode;
1831
+ this.startOffset = startOffset;
1821
1832
  }
1833
+ }
1834
+
1835
+ /**
1836
+ * The image block insert line break strategy.
1837
+ */
1838
+ class ImageInsertLineBreakStrategy extends codeBlock.ActionHandleStrategy {
1822
1839
  /**
1823
- * Obtain and format the style of element.
1840
+ * The image block not support insert the line break node, so invoke the insert new paragraph logic directly.
1824
1841
  *
1825
- * @param {HTMLElement} element - current element.
1826
- * @returns {AnnotationStyle} - Record<string, string>.
1842
+ * @param {LineBreakSingleBlockAction} action - The action instance.
1843
+ * @param {RTEImageBlock} target - The image block.
1827
1844
  */
1828
- generateCustomStyleAnnotations(element) {
1829
- const customStyle = element.getAttribute('style');
1830
- if (!customStyle)
1831
- return {};
1832
- const styleValue = customStyle.split(';').filter(Boolean);
1833
- return styleValue
1834
- .filter((key) => key !== ' ')
1835
- .map((key) => {
1836
- // to remove redundant quote pairs if needed, for example: ['fontFamily: "Roboto Mono"'] will be updated to ['fontFamily: Roboto Mono']
1837
- const styleObject = key.replace(/(['"])(.*?)\1/g, '$2').split(':');
1838
- const styleKey = string.dashCaseToCamel(styleObject[0].trim());
1839
- return {
1840
- [styleKey]: styleObject[1].trim().replace(';', ''),
1841
- };
1842
- })
1843
- .reduce((current, obj) => (Object.assign(Object.assign({}, current), obj)), {});
1845
+ handleAction(action, target) {
1846
+ const insertNewParagraphAction = new InsertNewParagraphAction(action.startContainerNode, action.startOffset);
1847
+ target.apply(insertNewParagraphAction);
1848
+ const newBlock = insertNewParagraphAction.newBlock;
1849
+ if (newBlock) {
1850
+ action.lineBreakNode = newBlock.children[0];
1851
+ }
1844
1852
  }
1845
1853
  }
1846
1854
 
1847
- /** Handle indent annotation */
1848
- class IndentAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1855
+ /**
1856
+ * Insert a line break node into multiple blocks selection at special position strategy.
1857
+ */
1858
+ class ImageInsertLineBreakWithBlocksStrategy extends codeBlock.ActionHandleStrategy {
1849
1859
  /**
1850
1860
  * @inheritDoc
1851
1861
  */
1852
- canHandle(targetDto) {
1853
- return ['RTETextBlock', 'RTEListItemBlock', 'RTEListBlock'].includes(targetDto.name);
1862
+ handleAction(action, target) {
1863
+ action.lineBreakNode = this.lineBreakMultipleBlocks(action.selectedBlocks, target);
1864
+ }
1865
+ /**
1866
+ * Inserts a new paragraph block with a line break after a selected block of text in a rich text editor.
1867
+ *
1868
+ * @param {RTEBlock[]} selectedBlocks - An array of RTEBlock objects that represent the blocks that have been selected for a specific action in the Rich Text Editor.
1869
+ * @param {RTEImageBlock} target - The image block.
1870
+ * @returns {Nullable<RTETextNode>} Returns a Nullable RTETextNode.
1871
+ */
1872
+ lineBreakMultipleBlocks(selectedBlocks, target) {
1873
+ const newParagraph = codeBlock.RTETextBlock.from({
1874
+ id: createPublicApiRuntimeMetricsSlimmer.generateUUID(),
1875
+ type: 'paragraph',
1876
+ nodes: [{ id: createPublicApiRuntimeMetricsSlimmer.generateUUID(), type: 'text', text: '\n' }],
1877
+ });
1878
+ target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newParagraph));
1879
+ const afterNodes = this.concatBlocksNodes(selectedBlocks.slice(1));
1880
+ if (afterNodes.length === 0 || (afterNodes[0] && afterNodes[0].text === '')) {
1881
+ afterNodes.push(new codeBlock.RTETextNode(createPublicApiRuntimeMetricsSlimmer.generateUUID(), '\n', newParagraph));
1882
+ }
1883
+ newParagraph.apply(new codeBlock.AppendChildrenAction(afterNodes));
1884
+ return newParagraph['children'][0];
1854
1885
  }
1855
1886
  /**
1856
- * Handle annotation.
1887
+ * Concat the child nodes of multiple RTEBlocks if both are not images.
1857
1888
  *
1858
- * @param {HTMLElement} element - Current elements.
1859
- * @returns {VegaRTEBlockAnnotations} - Annotation.
1889
+ * @param {RTEBlock[]} blocks - multiple block of content in a rich text editor, such as a paragraph, heading, image, etc.
1890
+ * @returns {RTENode[]} Array of connected block nodes
1860
1891
  */
1861
- handle(element) {
1862
- const indent = this.getIndent(element);
1863
- return indent ? { indent: indent } : {};
1892
+ concatBlocksNodes(blocks) {
1893
+ const nodes = [];
1894
+ blocks.map((block) => {
1895
+ if (block.type !== 'image') {
1896
+ nodes.push(...block.children);
1897
+ block.parent.apply(new codeBlock.RemoveChildrenAction(block));
1898
+ }
1899
+ });
1900
+ return nodes;
1864
1901
  }
1902
+ }
1903
+
1904
+ /**
1905
+ * Insert a image node at the special position of image block.
1906
+ */
1907
+ class ImageBlockInsertImageStrategy extends codeBlock.ActionHandleStrategy {
1865
1908
  /**
1866
- * Get indent of current element.
1867
- *
1868
- * @param {HTMLElement} element - current element.
1869
- * @returns {Nullable<number>} - Indent.
1909
+ * @inheritDoc
1870
1910
  */
1871
- getIndent(element) {
1872
- const style = element.style;
1873
- let marginLeft;
1874
- if (style.marginLeft) {
1875
- marginLeft = style.marginLeft;
1911
+ handleAction(action, target) {
1912
+ const splitNode = action.splitPointNode;
1913
+ const startOffsetOfNode = action.startOffsetOfNode;
1914
+ const newImageBlock = action.imageBlockToBeInserted;
1915
+ const newImageNodes = newImageBlock.children;
1916
+ if (target.children.length < 1) {
1917
+ target.apply(new codeBlock.AppendChildrenAction(newImageNodes));
1876
1918
  }
1877
- else if (style.margin) {
1878
- const margins = style.margin.split(' ');
1879
- switch (margins.length) {
1880
- case 4:
1881
- marginLeft = margins[3];
1882
- break;
1883
- case 2:
1884
- case 3:
1885
- marginLeft = margins[1];
1886
- break;
1887
- default:
1888
- marginLeft = margins[0];
1889
- break;
1890
- }
1919
+ else if (this.isCaretPositionAtBlockEnd(target, splitNode, startOffsetOfNode)) {
1920
+ target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newImageBlock));
1921
+ }
1922
+ else if (this.isCaretPositionAtBlockStart(target, splitNode, startOffsetOfNode)) {
1923
+ target.parent.apply(new codeBlock.InsertChildrenBeforeAction(target, newImageBlock));
1891
1924
  }
1892
1925
  else {
1893
- return null;
1926
+ target.apply(new codeBlock.SplitBlockWithNodeAction(splitNode, startOffsetOfNode));
1927
+ target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newImageBlock));
1894
1928
  }
1895
- const marginLeftNumber = Number(marginLeft.replace('px', ''));
1896
- return marginLeftNumber && marginLeftNumber >= 0 ? Math.floor(marginLeftNumber / 16) : null;
1897
1929
  }
1898
1930
  }
1899
1931
 
1900
- /** Handle text align annotation */
1901
- class TextAlignAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1932
+ /**
1933
+ * Image block
1934
+ */
1935
+ class RTEImageBlock extends codeBlock.RTEBlock {
1936
+ constructor(id) {
1937
+ super(id);
1938
+ this.type = 'image';
1939
+ this.children = [];
1940
+ }
1902
1941
  /**
1903
- * Can be handle.
1942
+ * Converts a VegaRTEImageBlock object into an RTEImageBlock object by mapping nodes and creating annotations.
1904
1943
  *
1905
- * @param {RTEDtoClassPrototype} targetDto - Target DTO.
1906
- * @returns {boolean} - .
1944
+ * @param {VegaRTEImageBlock} block - The block object to be converted.
1945
+ * @param {VegaRTETransformOptions} options - Optional transformation options.
1946
+ * @returns {RTEImageBlock} An instance of `RTEImageBlock`
1907
1947
  */
1908
- canHandle(targetDto) {
1909
- return ['RTETextBlock', 'RTEListItemBlock', 'RTEListBlock'].includes(targetDto.name);
1948
+ static from(block, options = { autoMatchFormat: true }) {
1949
+ const imageBlock = new RTEImageBlock(block.id);
1950
+ const { annotations } = block;
1951
+ imageBlock.children = block.nodes.map((image) => RTEImageNode.from(image, imageBlock, options));
1952
+ if (annotations) {
1953
+ super.convertAnnotationsToMap(imageBlock.annotationMap, annotations);
1954
+ }
1955
+ return imageBlock;
1910
1956
  }
1911
1957
  /**
1912
- * Handle annotation.
1913
- *
1914
- * @param {HTMLElement} element - Current elements.
1915
- * @returns {VegaRTEBlockAnnotations} - Annotation.
1958
+ * @inheritDoc
1916
1959
  */
1917
- handle(element) {
1918
- const textAlign = this.getTextAlign(element);
1919
- return textAlign ? { textAlign: textAlign } : {};
1960
+ toJSON() {
1961
+ return Object.assign(Object.assign({}, super.toJSON()), { type: 'image', nodes: this.children.map((node) => node.toJSON()) });
1920
1962
  }
1921
1963
  /**
1922
- * Get text align of current element.
1923
- *
1924
- * @param {HTMLElement} element - current element.
1925
- * @returns {Nullable<VegaRTEBlockAlignment>} - Text align.
1964
+ * @inheritDoc
1926
1965
  */
1927
- getTextAlign(element) {
1928
- const classList = element.classList;
1929
- if (classList.contains(`v-rte--horizontal-alignment-left`)) {
1930
- return 'left';
1931
- }
1932
- else if (classList.contains(`v-rte--horizontal-alignment-center`)) {
1933
- return 'center';
1934
- }
1935
- else if (classList.contains(`v-rte--horizontal-alignment-right`)) {
1936
- return 'right';
1937
- }
1938
- else if (classList.contains(`v-rte--horizontal-alignment-justify`)) {
1939
- return 'justify';
1940
- }
1941
- const style = element.style;
1942
- switch (style.textAlign) {
1943
- case 'center':
1944
- return 'center';
1945
- case 'right':
1946
- return 'right';
1947
- case 'justify':
1948
- return 'justify';
1949
- case 'left':
1950
- return 'left';
1951
- default:
1952
- return null;
1953
- }
1966
+ toHtml() {
1967
+ const attrStr = super.generateAttributeString();
1968
+ const children = this.children.map((node) => node.toHtml()).join('');
1969
+ return super.shouldRenderAsInternalWrapper()
1970
+ ? children
1971
+ : [`<div${attrStr}>`, children, `</div>`].join('');
1954
1972
  }
1955
- }
1956
-
1957
- /** Handle code annotation */
1958
- class CodeAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1959
1973
  /**
1960
1974
  * @inheritDoc
1961
1975
  */
1962
- canHandle(targetDto) {
1963
- return targetDto.name === 'RTETextNode';
1976
+ isNotEmpty() {
1977
+ return this.children.length > 0 && this.children.some((node) => node.url.length > 0);
1964
1978
  }
1965
1979
  /**
1966
- * Handle annotation.
1967
- *
1968
- * @param {HTMLElement} element - Current elements.
1969
- * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
1970
- * @returns {VegaRTETextAnnotations} - Annotation.
1980
+ * @inheritDoc
1971
1981
  */
1972
- handle(element, parentAnnotations = {}) {
1973
- return this.isCode(element) || parentAnnotations.code ? { code: true } : {};
1982
+ getLastNode() {
1983
+ return this.children[this.children.length - 1];
1974
1984
  }
1975
1985
  /**
1976
- * Is code element.
1986
+ * Create a new image block.
1977
1987
  *
1978
- * @param {HTMLElement} element - current element.
1979
- * @returns {boolean} - boolean.
1988
+ * @returns {RTEImageBlock} - The empty image block.
1980
1989
  */
1981
- isCode(element) {
1982
- return (element.classList.contains('v-rte--code') ||
1983
- element.nodeName === 'CODE' ||
1984
- element.nodeName === 'PRE' ||
1985
- element.style.fontFamily === 'monospace' ||
1986
- element.style.fontFamily.replace(/["']/g, '') === 'Roboto Mono');
1990
+ createNewImageBlock() {
1991
+ return new RTEImageBlock(createPublicApiRuntimeMetricsSlimmer.generateUUID());
1987
1992
  }
1988
- }
1989
-
1990
- /** Handle color annotation */
1991
- class ColorAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
1992
1993
  /**
1993
1994
  * @inheritDoc
1994
1995
  */
1995
- canHandle(targetDto) {
1996
- return targetDto.name === 'RTETextNode';
1996
+ clone() {
1997
+ const clonedBlock = new RTEImageBlock(this.id);
1998
+ clonedBlock.children = this.children.map((node) => {
1999
+ const clonedNode = node.clone();
2000
+ clonedNode.parent = clonedBlock;
2001
+ return clonedNode;
2002
+ });
2003
+ clonedBlock.annotationMap = super.cloneAnnotations();
2004
+ clonedBlock.parent = this.parent;
2005
+ return clonedBlock;
1997
2006
  }
1998
- /**
1999
- * Handle annotation.
2000
- *
2001
- * @param {HTMLElement} element - Current elements.
2002
- * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
2003
- * @returns {VegaRTETextAnnotations} - Annotation.
2004
- */
2005
- handle(element, parentAnnotations = {}) {
2006
- const color = this.getColor(element) || parentAnnotations.textColor;
2007
- return color ? { textColor: color } : {};
2007
+ }
2008
+ (() => {
2009
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.MERGE_TWO_BLOCKS_NODES, RTEImageBlock.name, new codeBlock.BlockMergeNodesStrategy());
2010
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.REPLACE_CHILD_NODES, RTEImageBlock.name, new codeBlock.BlockReplaceNodesStrategy());
2011
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.SPLIT_BLOCK_WITH_NODE, RTEImageBlock.name, new BlockSplitWithImageNodeStrategy());
2012
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.LINE_BREAK_SINGLE_BLOCK, RTEImageBlock.name, new ImageInsertLineBreakStrategy());
2013
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.LINE_BREAK_MULTIPLE_BLOCKS, RTEImageBlock.name, new ImageInsertLineBreakWithBlocksStrategy());
2014
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_IMAGE_TO_BLOCK, RTEImageBlock.name, new ImageBlockInsertImageStrategy());
2015
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.HorizontalAlignmentAnnotationAction.name, RTEImageBlock.name, new codeBlock.BlockUpdateHorizontalAlignmentStrategy());
2016
+ })();
2017
+
2018
+ /**
2019
+ * HTML Block
2020
+ */
2021
+ class RTEHtmlBlock extends codeBlock.RTEBlock {
2022
+ constructor(id, htmlTag) {
2023
+ super(id);
2024
+ this.type = 'html-block';
2025
+ this.children = [];
2026
+ this.htmlTag = htmlTag;
2008
2027
  }
2009
2028
  /**
2010
- * Get current color of element.
2029
+ * Converts a VegaRTEHtmlBlock to an RTEHtmlBlock.
2011
2030
  *
2012
- * @param {HTMLElement} element - current element.
2013
- * @returns {Nullable<string>} - color.
2031
+ * @param {VegaRTEHtmlBlock} block - The VegaRTEHtmlBlock to convert.
2032
+ * @param {VegaRTETransformOptions} [options] - Optional transformation options.
2033
+ * @returns {RTEHtmlBlock} The converted RTEHtmlBlock.
2014
2034
  */
2015
- getColor(element) {
2016
- var _a;
2017
- const color = element.style.color;
2018
- const hexColor = (_a = ui.rgbToHex(color)) === null || _a === void 0 ? void 0 : _a.toUpperCase();
2019
- if (hexColor) {
2020
- // We don't display default text color as inline style, because we defined it in the vega-rich-text-content.scss.
2021
- const colorSchema = codeBlock.RTE_TEXT_COLORS.filter((item) => item.key !== codeBlock.RTE_DEFAULT_TEXT_COLOR.key).find((schema) => schema.light === hexColor || schema.dark === hexColor);
2022
- if (colorSchema)
2023
- return colorSchema.key;
2024
- return null;
2025
- }
2026
- else {
2027
- for (const color of codeBlock.RTE_TEXT_COLORS) {
2028
- if (element.style.color.includes(color.key)) {
2029
- return color.key;
2030
- }
2031
- }
2032
- return null;
2035
+ static from(block, options) {
2036
+ const htmlBlock = new RTEHtmlBlock(block.id, block.htmlTag);
2037
+ const { annotations } = block;
2038
+ if (annotations) {
2039
+ super.convertAnnotationsToMap(htmlBlock.annotationMap, annotations);
2033
2040
  }
2041
+ htmlBlock.children = block.children
2042
+ .map((child) => {
2043
+ const BlockClass = codeBlock.RTEDTOClassManager.getRTEBlockClass(child.type);
2044
+ if (BlockClass) {
2045
+ const block = BlockClass.from(child, options);
2046
+ block.parent = htmlBlock;
2047
+ return block;
2048
+ }
2049
+ })
2050
+ .filter(typeGuard.isNonNullable);
2051
+ return htmlBlock;
2034
2052
  }
2035
- }
2036
-
2037
- /** Handle italic annotation */
2038
- class ItalicAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
2039
2053
  /**
2040
2054
  * @inheritDoc
2041
2055
  */
2042
- canHandle(targetDto) {
2043
- return targetDto.name === 'RTETextNode';
2056
+ clone() {
2057
+ const clonedBlock = new RTEHtmlBlock(this.id, this.htmlTag);
2058
+ clonedBlock.children = this.children.map((child) => child.clone());
2059
+ clonedBlock.annotationMap = super.cloneAnnotations();
2060
+ return clonedBlock;
2044
2061
  }
2045
2062
  /**
2046
- * Handle annotation.
2047
- *
2048
- * @param {HTMLElement} element - Current elements.
2049
- * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
2050
- * @returns {VegaRTETextAnnotations} - Annotation.
2063
+ * @inheritDoc
2051
2064
  */
2052
- handle(element, parentAnnotations = {}) {
2053
- return this.isItalic(element) || parentAnnotations.italic ? { italic: true } : {};
2065
+ getLastNode() {
2066
+ return this.children[this.children.length - 1].getLastNode();
2054
2067
  }
2055
2068
  /**
2056
- * Is italic element.
2057
- *
2058
- * @param {HTMLElement} element - current element.
2059
- * @returns {boolean} - boolean.
2069
+ * @inheritDoc
2060
2070
  */
2061
- isItalic(element) {
2062
- return (element.nodeName === 'I' ||
2063
- element.style.fontStyle === 'italic' ||
2064
- element.nodeName === 'EM' ||
2065
- element.classList.contains('v-rte--italic'));
2066
- }
2067
- }
2068
-
2069
- /** Handle link annotation */
2070
- class LinkAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
2071
- constructor() {
2072
- super(...arguments);
2073
- this.handlers = [
2074
- new CustomAttributeAnnotationHandler(),
2075
- new CustomClassAnnotationHandler(),
2076
- new CustomStyleAnnotationHandler(),
2077
- ];
2071
+ isNotEmpty() {
2072
+ return this.children.length > 0;
2078
2073
  }
2079
2074
  /**
2080
- * Can be handle.
2081
- *
2082
- * @param {RTEDtoClassPrototype} targetDto - Target DTO.
2083
- * @returns {boolean} - .
2075
+ * @inheritDoc
2084
2076
  */
2085
- canHandle(targetDto) {
2086
- return targetDto.name === 'RTETextNode';
2077
+ toHtml() {
2078
+ const BlockTag = this.htmlTag;
2079
+ const attrStr = super.generateAttributeString();
2080
+ return [
2081
+ `<${BlockTag}${attrStr}>`,
2082
+ this.children.map((block) => block.toHtml()).join(''),
2083
+ `</${BlockTag}>`,
2084
+ ].join('');
2087
2085
  }
2088
2086
  /**
2089
- * Handle annotation.
2090
- *
2091
- * @param {HTMLElement} element - Current elements.
2092
- * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
2093
- * @returns {VegaRTETextAnnotations} - Annotation.
2087
+ * @inheritDoc
2094
2088
  */
2095
- handle(element, parentAnnotations = {}) {
2096
- if (parentAnnotations.link)
2097
- return { link: parentAnnotations.link };
2098
- return element.tagName === 'A' ? { link: this.generateLinkAnnotations(element) } : {};
2089
+ toJSON() {
2090
+ return Object.assign(Object.assign({}, super.toJSON()), { id: this.id, type: this.type, htmlTag: this.htmlTag, children: this.children.map((child) => child.toJSON()) });
2099
2091
  }
2100
- /**
2101
- * Generate link annotations.
2102
- *
2103
- * @param {HTMLElement} element - Current elements.
2104
- * @returns {VegaRTELink} - link annotations.
2105
- */
2106
- generateLinkAnnotations(element) {
2107
- const annotations = {
2108
- href: element.getAttribute('href') || '',
2109
- groupKey: createPublicApiRuntimeMetricsSlimmer.generateUUID(),
2110
- };
2111
- this.handlers.forEach((handler) => {
2112
- Object.assign(annotations, handler.handle(element));
2113
- });
2114
- return annotations;
2092
+ }
2093
+
2094
+ /**
2095
+ * Merge the two blocks node into first block if the two blocks nodes type is same(text node or image node)
2096
+ *
2097
+ * @example firstBlock.apply(new MergeTwoBlocksNodesAction(secondBlock))
2098
+ */
2099
+ class MergeTwoBlocksNodesAction extends codeBlock.ModifyContentAction {
2100
+ constructor(blockNeedToBeMerged) {
2101
+ super();
2102
+ this.type = codeBlock.ModifyContentActionType.MERGE_TWO_BLOCKS_NODES;
2103
+ this.blockNeedToBeMerged = blockNeedToBeMerged;
2115
2104
  }
2116
2105
  }
2117
2106
 
2118
- /** Handle strike through annotation */
2119
- class StrikeThroughAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
2107
+ /**
2108
+ * Block delete text or decorator node strategy.
2109
+ */
2110
+ class BlockDeleteTextOrDecoratorNodeStrategy extends codeBlock.BlockDeleteNodeContentStrategy {
2120
2111
  /**
2121
2112
  * @inheritDoc
2122
2113
  */
2123
- canHandle(targetDto) {
2124
- return targetDto.name === 'RTETextNode';
2114
+ handleAction(action, target) {
2115
+ const { startContainerNode } = action;
2116
+ if (!startContainerNode.isContentEditable()) {
2117
+ this.deleteDecoratorNodeContent(action, target);
2118
+ }
2119
+ else if (startContainerNode.isTextNode()) {
2120
+ this.deleteTextNodeContent(action, target);
2121
+ }
2122
+ const parent = target.parent;
2123
+ if (parent && target.isListItemBlock() && parent.children.length === 0) {
2124
+ parent.parent.apply(new codeBlock.RemoveChildrenAction(parent));
2125
+ }
2125
2126
  }
2126
2127
  /**
2127
- * Handle annotation.
2128
+ * Handle the delete text logic when press delete key.
2128
2129
  *
2129
- * @param {HTMLElement} element - Current elements.
2130
- * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
2131
- * @returns {VegaRTETextAnnotations} - Annotation.
2130
+ * @param {DeleteBlockContentAction} action - ModifyContentAction
2131
+ * @param {RTETextBlock} target - Current text block
2132
2132
  */
2133
- handle(element, parentAnnotations = {}) {
2134
- return this.isStrikethrough(element) || parentAnnotations.strikethrough
2135
- ? { strikethrough: true }
2136
- : {};
2133
+ deleteTextNodeContent(action, target) {
2134
+ const startContainerNode = action.startContainerNode;
2135
+ const startOffset = action.startOffset;
2136
+ if (startOffset !== 0 && !startContainerNode.isEmpty()) {
2137
+ const newText = startContainerNode.text.slice(0, startOffset - 1) +
2138
+ startContainerNode.text.slice(startOffset);
2139
+ startContainerNode.apply(new codeBlock.UpdateTextAction(newText));
2140
+ if (newText) {
2141
+ action.previousNode = startContainerNode;
2142
+ return;
2143
+ }
2144
+ else {
2145
+ const previousNode = this.getPreviousNode(startContainerNode);
2146
+ // Remove the last character will not delete paragraph, the paragraph will removed after press delete again
2147
+ if ((previousNode && previousNode.parent === target && previousNode['text'] === '\n') ||
2148
+ target.children.length === 1) {
2149
+ action.previousNode = startContainerNode;
2150
+ return;
2151
+ }
2152
+ else {
2153
+ target.apply(new codeBlock.RemoveChildrenAction(startContainerNode));
2154
+ action.previousNode = previousNode;
2155
+ return;
2156
+ }
2157
+ }
2158
+ }
2159
+ else {
2160
+ let previousNode = this.getPreviousNode(startContainerNode);
2161
+ let nextNode = null;
2162
+ const isCurrentNodeEmpty = startContainerNode.isEmpty();
2163
+ if (target.children.length && previousNode && previousNode.parent !== target) {
2164
+ if (isCurrentNodeEmpty) {
2165
+ target.apply(new codeBlock.RemoveChildrenAction(startContainerNode));
2166
+ }
2167
+ if (target.type === previousNode.parent.type) {
2168
+ previousNode.parent.apply(new MergeTwoBlocksNodesAction(target));
2169
+ }
2170
+ }
2171
+ else {
2172
+ if (this.isContentFirstNode(startContainerNode) && isCurrentNodeEmpty) {
2173
+ nextNode = this.getNextNode(startContainerNode);
2174
+ }
2175
+ /**
2176
+ * Remove line break
2177
+ *
2178
+ * @example caret at the first line
2179
+ * \n
2180
+ * test
2181
+ */
2182
+ if (isCurrentNodeEmpty) {
2183
+ target.apply(new codeBlock.RemoveChildrenAction(startContainerNode));
2184
+ }
2185
+ /**
2186
+ * Remove line break or non-editable node
2187
+ *
2188
+ * @example caret at the begin of second line
2189
+ * \n
2190
+ * test
2191
+ * @example caret at the end of non-editable node and start of the text node
2192
+ * <img/><span>test</span>
2193
+ */
2194
+ if (previousNode &&
2195
+ previousNode.isTextNode() &&
2196
+ (previousNode.isEmpty() ||
2197
+ (!previousNode.isContentEditable() && previousNode.parent === target))) {
2198
+ const shouldRemoveNode = previousNode;
2199
+ previousNode = this.getPreviousNode(previousNode);
2200
+ shouldRemoveNode.parent.apply(new codeBlock.RemoveChildrenAction(shouldRemoveNode));
2201
+ if (!previousNode && !isCurrentNodeEmpty) {
2202
+ nextNode = startContainerNode;
2203
+ }
2204
+ }
2205
+ }
2206
+ //Remove the paragraph block if the content is empty
2207
+ if (target.children.length === 0) {
2208
+ target.parent.apply(new codeBlock.RemoveChildrenAction(target));
2209
+ }
2210
+ if (previousNode) {
2211
+ action.previousNode = previousNode;
2212
+ }
2213
+ else if (nextNode) {
2214
+ action.nextNode = nextNode;
2215
+ }
2216
+ }
2137
2217
  }
2138
2218
  /**
2139
- * Is strikethrough element.
2219
+ * Delete decorator node content
2140
2220
  *
2141
- * @param {HTMLElement} element - current element.
2142
- * @returns {boolean} - boolean.
2221
+ * @param {DeleteBlockContentAction} action - The delete block content action
2222
+ * @param {RTEBlock} target - The target block
2143
2223
  */
2144
- isStrikethrough(element) {
2145
- return (element.style.textDecoration.includes('line-through') ||
2146
- element.nodeName === 'S' ||
2147
- element.nodeName === 'DEL' ||
2148
- element.classList.contains('v-rte--strikethrough'));
2224
+ deleteDecoratorNodeContent(action, target) {
2225
+ const startContainerNode = action.startContainerNode, startOffset = action.startOffset;
2226
+ let previousNode = this.getPreviousNode(startContainerNode);
2227
+ let nextNode = null;
2228
+ if (startOffset !== 0) {
2229
+ const parentBlock = target;
2230
+ if (this.isContentFirstNode(startContainerNode)) {
2231
+ nextNode = this.getNextNode(startContainerNode);
2232
+ }
2233
+ if (parentBlock.children.length === 1) {
2234
+ parentBlock.parent.apply(new codeBlock.RemoveChildrenAction(parentBlock));
2235
+ }
2236
+ else {
2237
+ parentBlock.apply(new codeBlock.RemoveChildrenAction(startContainerNode));
2238
+ }
2239
+ }
2240
+ else {
2241
+ const shouldRemoveNode = previousNode;
2242
+ if (shouldRemoveNode && !shouldRemoveNode.isContentEditable()) {
2243
+ previousNode = this.getPreviousNode(shouldRemoveNode);
2244
+ shouldRemoveNode.parent.apply(new codeBlock.RemoveChildrenAction(shouldRemoveNode));
2245
+ if (!previousNode) {
2246
+ action.nextNode = startContainerNode;
2247
+ }
2248
+ }
2249
+ }
2250
+ if (previousNode) {
2251
+ action.previousNode = previousNode;
2252
+ }
2253
+ else if (nextNode) {
2254
+ action.nextNode = nextNode;
2255
+ }
2149
2256
  }
2150
2257
  }
2151
2258
 
2152
- /** Handle underline annotation */
2153
- class UnderlineAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
2259
+ /**
2260
+ * Insert new paragraph into current block at special position.
2261
+ */
2262
+ class BlockInsertNewParagraphStrategy extends codeBlock.ActionHandleStrategy {
2154
2263
  /**
2155
2264
  * @inheritDoc
2156
2265
  */
2157
- canHandle(targetDto) {
2158
- return targetDto.name === 'RTETextNode';
2266
+ handleAction(action, target) {
2267
+ const { startContainerNode } = action;
2268
+ action.newBlock = this.breakSingleBlock(startContainerNode, action.startOffset, target);
2159
2269
  }
2160
2270
  /**
2161
- * Handle annotation.
2271
+ * breakSingleTextBlock
2162
2272
  *
2163
- * @param {HTMLElement} element - Current elements.
2164
- * @param {VegaRTETextAnnotations} parentAnnotations - Parent annotations.
2165
- * @returns {VegaRTETextAnnotations} - Annotation.
2273
+ * @param {RTETextNode} splitNode -
2274
+ * @param {number} startOffsetOfNode -
2275
+ * @param {RTEBlock} target -
2276
+ * @returns {Nullable<RTEBlock>} Nullable<RTEBlock>
2166
2277
  */
2167
- handle(element, parentAnnotations = {}) {
2168
- return this.isUnderline(element) || parentAnnotations.underline ? { underline: true } : {};
2278
+ breakSingleBlock(splitNode, startOffsetOfNode, target) {
2279
+ const newParagraph = this.getNewParagraph(splitNode);
2280
+ if (newParagraph) {
2281
+ if (this.isCaretPositionAtBlockEnd(target, splitNode, startOffsetOfNode)) {
2282
+ target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newParagraph));
2283
+ }
2284
+ else if (this.isCaretPositionAtBlockStart(target, splitNode, startOffsetOfNode)) {
2285
+ target.parent.apply(new codeBlock.InsertChildrenBeforeAction(target, newParagraph));
2286
+ }
2287
+ else {
2288
+ const splitBlockAction = new codeBlock.SplitBlockWithNodeAction(splitNode, startOffsetOfNode);
2289
+ target.apply(splitBlockAction);
2290
+ return splitBlockAction.newBlock;
2291
+ }
2292
+ return newParagraph;
2293
+ }
2169
2294
  }
2170
2295
  /**
2171
- * Is underline element.
2296
+ * Create new Paragraph
2172
2297
  *
2173
- * @param {HTMLElement} element - current element.
2174
- * @returns {boolean} - boolean.
2298
+ * @param {RTENode} splitNode - The split node of the block.
2299
+ * @returns {Nullable<RTETextBlock>} - The new text block.
2175
2300
  */
2176
- isUnderline(element) {
2177
- return (element.style.textDecoration.includes('underline') ||
2178
- element.nodeName === 'U' ||
2179
- element.nodeName === 'INS' ||
2180
- element.classList.contains('v-rte--underline'));
2301
+ getNewParagraph(splitNode) {
2302
+ const newParagraph = this.createNewParagraph('');
2303
+ if (newParagraph) {
2304
+ let textNode = newParagraph.children[0];
2305
+ if (splitNode.isTextNode() && splitNode.isContentEditable()) {
2306
+ newParagraph.children = [];
2307
+ textNode = splitNode.cloneWithText('');
2308
+ // The link annotation don't need inherited
2309
+ textNode.annotationMap.delete(codeBlock.NodeAnnotationTypeEnum.LINK);
2310
+ newParagraph.apply(new codeBlock.AppendChildrenAction([textNode]));
2311
+ }
2312
+ return newParagraph;
2313
+ }
2181
2314
  }
2182
2315
  }
2183
2316
 
2184
- /** Handle text style annotation */
2185
- class TextStyleAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
2186
- /**
2187
- * Can be handle.
2188
- *
2189
- * @param {RTEDtoClassPrototype} targetDto - Target DTO.
2190
- * @param {HtmlElementToAnnotationGenerateOptions} options - Options for annotation generator.
2191
- * @returns {boolean} - .
2192
- */
2193
- canHandle(targetDto, options) {
2194
- return !!options.autoMatchFormat && targetDto.name === 'RTETextBlock';
2195
- }
2196
- /**
2197
- * Handle annotation.
2198
- *
2199
- * @param {HTMLElement} element - Current elements.
2200
- * @returns {VegaRTETextBlockAnnotations} - Annotation.
2201
- */
2202
- handle(element) {
2203
- const textStyle = this.getTextStyle(element);
2204
- return textStyle ? { textStyle: textStyle } : {};
2205
- }
2317
+ /**
2318
+ * Update the cursor position in the editor.
2319
+ *
2320
+ * @example richEditorRef.value.apply(new UpdateCursorPositionAction(nextFocusNode, [offset], [immediatelyRun]))
2321
+ */
2322
+ class UpdateCursorPositionAction extends codeBlock.ModifyContentAction {
2206
2323
  /**
2207
- * Get the node type of element. The element type is determined in the following
2208
- * order: "data-type" attribute, node name, font size and class name.
2324
+ * Set the cursor position at end of the current node.
2209
2325
  *
2210
- * @param {HTMLElement} element - element.
2211
- * @returns {Nullable<VegaRTETextStyleType>} - node type.
2326
+ * @param {RTENode} nextFocusNode - The rich text editor needs focus node.
2327
+ * @param {number} offset - The cursor offset position.
2328
+ * @param {boolean} immediatelyRun - Whether to immediately set the cursor position after applying it. Usually the set action will trigger after the UI renders.
2212
2329
  */
2213
- getTextStyle(element) {
2214
- const byDataType = this.getElementTypeByDataType(element);
2215
- if (byDataType)
2216
- return byDataType;
2217
- const byNodeName = this.getElementTypeByNodeName(element);
2218
- if (byNodeName)
2219
- return byNodeName;
2220
- const byFontSize = this.getElementTypeByFontSize(element);
2221
- if (byFontSize)
2222
- return byFontSize;
2223
- const byClassName = this.getElementTypeByClassName(element);
2224
- if (byClassName)
2225
- return byClassName;
2226
- return null;
2330
+ constructor(nextFocusNode, offset, immediatelyRun = false) {
2331
+ super();
2332
+ this.type = codeBlock.ModifyContentActionType.UPDATE_CURSOR_POSITION;
2333
+ this.immediatelyRun = false;
2334
+ this.nextFocusNode = nextFocusNode;
2335
+ this.offset = offset;
2336
+ this.immediatelyRun = immediatelyRun;
2227
2337
  }
2338
+ }
2339
+
2340
+ /**
2341
+ * Insert a new node in nearest position of parent block strategy.
2342
+ */
2343
+ class InsertNodeToNearestRootStrategy extends codeBlock.ActionHandleStrategy {
2228
2344
  /**
2229
- * Get the element type by data-type attribute.
2230
- *
2231
- * @param {HTMLElement} element - element.
2232
- * @returns {Nullable<VegaRTETextStyleType>} - element type or null if not found.
2345
+ * @inheritDoc
2233
2346
  */
2234
- getElementTypeByDataType(element) {
2235
- if (element.nodeType !== Node.TEXT_NODE && element.hasAttribute('data-type')) {
2236
- return element.getAttribute('data-type');
2347
+ handleAction(action, target) {
2348
+ const { rteRange, nodeToBeInserted } = action;
2349
+ const { startNode, startOffset } = rteRange;
2350
+ if (startNode) {
2351
+ const parent = target;
2352
+ if (startNode.isContentEditable() && startNode.isTextNode()) {
2353
+ if (startNode.text === '\n' || !startNode.text || startOffset === 0) {
2354
+ parent.apply(new codeBlock.InsertChildrenBeforeAction(startNode, nodeToBeInserted));
2355
+ }
2356
+ else {
2357
+ const startText = startNode.text.substring(0, startOffset);
2358
+ const endText = startNode.text.substring(startOffset);
2359
+ const startTextNode = startNode.cloneWithText(startText);
2360
+ const endTextNode = startNode.cloneWithText(endText);
2361
+ const insertNodes = [startTextNode, nodeToBeInserted];
2362
+ if (endText) {
2363
+ insertNodes.push(endTextNode);
2364
+ }
2365
+ parent.apply(new codeBlock.InsertChildrenBeforeAction(startNode, ...insertNodes));
2366
+ parent.apply(new codeBlock.RemoveChildrenAction(startNode));
2367
+ }
2368
+ }
2369
+ else {
2370
+ if (startOffset !== 0) {
2371
+ parent.apply(new codeBlock.InsertChildrenAfterAction(startNode, nodeToBeInserted));
2372
+ }
2373
+ else {
2374
+ parent.apply(new codeBlock.InsertChildrenBeforeAction(startNode, nodeToBeInserted));
2375
+ }
2376
+ }
2377
+ this.updateCursorPosition(nodeToBeInserted);
2237
2378
  }
2238
- return null;
2239
2379
  }
2240
2380
  /**
2241
- * Get the element type by font size.
2381
+ * Update the cursor position to end of the inserted node.
2242
2382
  *
2243
- * @param {HTMLElement} element - element.
2244
- * @returns {Nullable<VegaRTETextStyleType>} - element type or null if not found.
2383
+ * @param {RTENode} node - node to find root content
2245
2384
  */
2246
- getElementTypeByFontSize(element) {
2247
- var _a;
2248
- switch ((_a = element.style) === null || _a === void 0 ? void 0 : _a.fontSize) {
2249
- case '36px':
2250
- return 'title';
2251
- case '28px':
2252
- return 'subtitle';
2253
- case '22px':
2254
- return 'heading-1';
2255
- case '20px':
2256
- return 'heading-2';
2257
- case '18px':
2258
- return 'heading-3';
2259
- default:
2260
- return null;
2385
+ updateCursorPosition(node) {
2386
+ const root = this.getRootContent(node.parent);
2387
+ if (root) {
2388
+ root.apply(new UpdateCursorPositionAction(node));
2261
2389
  }
2262
2390
  }
2391
+ }
2392
+
2393
+ /**
2394
+ * Strategy for inserting text into a decorator node. The decorator can not edit, so we insert the text as a new child.
2395
+ */
2396
+ class InsertTextToDecoratorNodeStrategy extends codeBlock.ActionHandleStrategy {
2263
2397
  /**
2264
- * Get the element type by node name.
2265
- *
2266
- * @param {HTMLElement} element - element.
2267
- * @returns {Nullable<VegaRTETextStyleType>} - element type or null if not found.
2398
+ * @inheritDoc
2268
2399
  */
2269
- getElementTypeByNodeName(element) {
2270
- switch (element.nodeName) {
2271
- case 'H1':
2272
- return 'heading-1';
2273
- case 'H2':
2274
- return 'heading-2';
2275
- case 'H3':
2276
- return 'heading-3';
2277
- case 'H4':
2278
- return 'heading-4';
2279
- case 'H5':
2280
- return 'heading-5';
2281
- case 'H6':
2282
- return 'heading-6';
2283
- default:
2284
- return null;
2400
+ handleAction(action, target) {
2401
+ const { text, offset, decoratorNode } = action;
2402
+ const paragraph = this.createNewParagraph(text);
2403
+ if (paragraph) {
2404
+ const newTextNode = paragraph.children[0];
2405
+ if (offset !== 0) {
2406
+ target.apply(new codeBlock.InsertChildrenAfterAction(decoratorNode, newTextNode));
2407
+ }
2408
+ else {
2409
+ target.apply(new codeBlock.InsertChildrenBeforeAction(decoratorNode, newTextNode));
2410
+ }
2411
+ this.setTheCursorPosition(newTextNode);
2285
2412
  }
2286
2413
  }
2287
2414
  /**
2288
- * Get the element type by class name.
2415
+ * Set the cursor position to the new text node.
2289
2416
  *
2290
- * @param {HTMLElement} element - element.
2291
- * @returns {Nullable<VegaRTETextStyleType>} - element type or null if not found.
2417
+ * @param {RTENode} focusNode - The new text node to focus on.
2292
2418
  */
2293
- getElementTypeByClassName(element) {
2294
- if (element.className) {
2295
- const match = /\bv-rte--text-style-(title|subtitle|heading-1|heading-2|heading-3|paragraph)\b/.exec(element.className);
2296
- if (match) {
2297
- return match[1];
2298
- }
2419
+ setTheCursorPosition(focusNode) {
2420
+ const rootContent = this.getRootContent(focusNode.parent);
2421
+ if (rootContent) {
2422
+ rootContent.apply(new UpdateCursorPositionAction(focusNode));
2299
2423
  }
2300
- return null;
2301
2424
  }
2302
2425
  }
2303
2426
 
2304
- /** Handle image size annotation */
2305
- class ImageSizeAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
2427
+ /**
2428
+ * Insert new paragraph into current list item block at special position.
2429
+ */
2430
+ class ListItemInsertNewParagraphStrategy extends codeBlock.ActionHandleStrategy {
2306
2431
  /**
2307
2432
  * @inheritDoc
2308
2433
  */
2309
- canHandle(targetDto) {
2310
- return targetDto.name === 'RTEImageNode';
2311
- }
2312
- /**
2313
- * Handle annotation.
2314
- *
2315
- * @param {HTMLElement} element - Current elements.
2316
- * @returns {VegaRTEImageAnnotations} - Annotation.
2317
- */
2318
- handle(element) {
2319
- const size = this.getImageSize(element);
2320
- return size ? { size: size } : {};
2434
+ handleAction(action, target) {
2435
+ action.newBlock = this.breakSingleListItemBlock(action.startContainerNode, action.startOffset, target);
2321
2436
  }
2322
2437
  /**
2323
- * Determine the image display size based on the width of the current element.
2438
+ * Breaks a single list item block at a specific position.
2324
2439
  *
2325
- * @param {HTMLElement} element - current element.
2326
- * @returns {Nullable<VegaRichTextImageEditorSizeType>} -Image size, default 'md'.
2440
+ * @param {RTETextNode} splitNode - The node that needs to be split within a list item block.
2441
+ * @param {number} startOffsetOfNode - The index within the `splitNode` where the break operation should occur.
2442
+ * @param {RTEListItemBlock} target - The list item block.
2443
+ * @returns {Nullable<RTEBlock>} Returns either a new `RTEListItemBlock` if the caret
2444
+ * position is at the end of the `splitNode`, or it returns the result of splitting the block at the
2445
+ * caret position if it is neither at the start nor at the end.
2327
2446
  */
2328
- getImageSize(element) {
2329
- if (element.getAttribute('data-size')) {
2330
- return element.getAttribute('data-size');
2447
+ breakSingleListItemBlock(splitNode, startOffsetOfNode, target) {
2448
+ const newListItem = target.createNewListItem();
2449
+ const newBreakNode = this.copyInlineStyleToNewNode(splitNode);
2450
+ newListItem.apply(new codeBlock.AppendChildrenAction([newBreakNode]));
2451
+ if (this.isCaretPositionAtBlockEnd(target, splitNode, startOffsetOfNode)) {
2452
+ return this.breakListItemAtEnd(newListItem, target);
2453
+ }
2454
+ else if (this.isCaretPositionAtBlockStart(target, splitNode, startOffsetOfNode)) {
2455
+ target.parent.apply(new codeBlock.InsertChildrenBeforeAction(target, newListItem));
2456
+ }
2457
+ else {
2458
+ const splitBlockAction = new codeBlock.SplitBlockWithNodeAction(splitNode, startOffsetOfNode);
2459
+ target.apply(splitBlockAction);
2460
+ return splitBlockAction.newBlock;
2331
2461
  }
2332
- return null;
2462
+ return newListItem;
2333
2463
  }
2334
- }
2335
-
2336
- /** Handle image alt annotation */
2337
- class ImageAltAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
2338
2464
  /**
2339
- * @inheritDoc
2465
+ * Breaks a list item at the end and handles the insertion of a new list item or paragraph accordingly.
2466
+ *
2467
+ * @param {RTEListItemBlock} newListItem - Item that represents a new list item to be added to the existing list.
2468
+ * @param {RTEListItemBlock} target - The list item block.
2469
+ * @returns {RTEBlock} Returns a `RTEBlock`.
2340
2470
  */
2341
- canHandle(targetDto) {
2342
- return targetDto.name === 'RTEImageNode';
2471
+ breakListItemAtEnd(newListItem, target) {
2472
+ const lastItem = target.parent.children[target.parent.children.length - 1];
2473
+ const currentItemIsEmpty = target.children.length === 1 && target.children[0].isEmpty();
2474
+ if (target === lastItem && currentItemIsEmpty) {
2475
+ const parentParent = target.parent.parent;
2476
+ if (parentParent['type'] !== 'list-item') {
2477
+ const newParagraph = codeBlock.RTETextBlock.from({
2478
+ id: createPublicApiRuntimeMetricsSlimmer.generateUUID(),
2479
+ type: 'paragraph',
2480
+ nodes: [],
2481
+ });
2482
+ newParagraph.apply(new codeBlock.AppendChildrenAction(newListItem.children));
2483
+ parentParent.apply(new codeBlock.InsertChildrenAfterAction(target.parent, newParagraph));
2484
+ target.parent.apply(new codeBlock.RemoveChildrenAction(target));
2485
+ return newParagraph;
2486
+ }
2487
+ else {
2488
+ parentParent.parent.apply(new codeBlock.InsertChildrenAfterAction(parentParent, newListItem));
2489
+ target.parent.apply(new codeBlock.RemoveChildrenAction(target));
2490
+ }
2491
+ }
2492
+ else {
2493
+ target.parent.apply(new codeBlock.InsertChildrenAfterAction(target, newListItem));
2494
+ }
2495
+ return newListItem;
2343
2496
  }
2344
2497
  /**
2345
- * Handle annotation.
2498
+ * Copy the inline style to new node
2346
2499
  *
2347
- * @param {HTMLElement} element - Current elements.
2348
- * @returns {VegaRTEImageAnnotations} - Annotation.
2500
+ * @param {RTETextNode} needCopedNode - The node that needed to be copied to
2501
+ * @returns {RTETextNode} Returns a `RTETextNode`.
2349
2502
  */
2350
- handle(element) {
2351
- return element.hasAttribute('alt') ? { alt: element.getAttribute('alt') } : {};
2503
+ copyInlineStyleToNewNode(needCopedNode) {
2504
+ const textNode = needCopedNode.cloneWithText('');
2505
+ // The link annotation doesn't need to inherit
2506
+ textNode.annotationMap.delete(codeBlock.NodeAnnotationTypeEnum.LINK);
2507
+ return textNode;
2352
2508
  }
2353
2509
  }
2354
2510
 
2355
2511
  /**
2356
- * Handle inline html annotation
2512
+ * Delete the nest list block action
2513
+ *
2514
+ * @example needRemovedNestList.parent.apply(new RemoveNestListAction(needRemovedNestList))
2357
2515
  */
2358
- class InlineHtmlAnnotationHandler extends AnnotationGeneratorStrategyAbstract {
2359
- constructor() {
2360
- super(...arguments);
2361
- this.customAttributeHandler = new CustomAttributeAnnotationHandler();
2362
- this.customStyleAnnotationHandler = new CustomStyleAnnotationHandler();
2363
- this.customClassAnnotationHandler = new CustomClassAnnotationHandler();
2364
- }
2365
- /**
2366
- * @inheritDoc
2367
- */
2368
- canHandle(targetDto, options) {
2369
- return targetDto.name === 'RTETextNode' && options.autoMatchFormat === false;
2370
- }
2371
- /**
2372
- * @inheritDoc
2373
- */
2374
- handle(element, parentAnnotations) {
2375
- const canHandle = InlineHtmlAnnotationHandler.canHandleTags.includes(element.nodeName);
2376
- if (canHandle) {
2377
- const inlineHtml = this.generateInlineHtmlAnnotation(element, Object.assign({}, parentAnnotations));
2378
- if (inlineHtml) {
2379
- return { inlineHtml: inlineHtml };
2380
- }
2381
- }
2382
- return {};
2516
+ class RemoveNestListAction extends codeBlock.ModifyContentAction {
2517
+ constructor(childList) {
2518
+ super();
2519
+ this.type = codeBlock.ModifyContentActionType.DELETE_NEST_LIST;
2520
+ this.nestListBlockToBeRemoved = childList;
2383
2521
  }
2522
+ }
2523
+
2524
+ /**
2525
+ * List remove list item strategy.
2526
+ */
2527
+ class ListRemoveListItemStrategy extends codeBlock.RemoveChildrenStrategy {
2384
2528
  /**
2385
- * Generate inline html annotation.
2529
+ * Remove the list item, check the list item and remove self if the list item is empty.
2386
2530
  *
2387
- * @param {HTMLElement} child - Current element.
2388
- * @param {VegaRTETextAnnotations} annotations - Current annotations.
2389
- * @returns {Nullable<VegaInlineHtmlSchema>} - Inline html annotation.
2531
+ * @param {RemoveChildrenAction} action - The remove action instance.
2532
+ * @param {RTEListBlock} target - The list block.
2390
2533
  */
2391
- generateInlineHtmlAnnotation(child, annotations) {
2392
- let { inlineHtml } = annotations;
2393
- if (!codeBlock.RTETextNode.supportsHtmlTag(child.nodeName.toLowerCase()) ||
2394
- (child.childNodes.length === 1 && child.childNodes[0].nodeType !== Node.TEXT_NODE)) {
2395
- const childInlineHtmlNode = {
2396
- htmlTag: child.nodeName.toLowerCase(),
2397
- customAttribute: this.customAttributeHandler.handle(child).customAttribute,
2398
- customStyle: this.customStyleAnnotationHandler.handle(child).customStyle,
2399
- customClass: this.customClassAnnotationHandler.handle(child).customClass,
2400
- };
2401
- if (!inlineHtml) {
2402
- inlineHtml = childInlineHtmlNode;
2534
+ handleAction(action, target) {
2535
+ super.handleAction(action, target);
2536
+ const parent = target.parent;
2537
+ if (target.children.length === 0 && parent) {
2538
+ // The parent is a list item mean the current block is a nest list, so we need to use RemoveNestListAction to remove the item
2539
+ if (parent['type'] === 'list-item') {
2540
+ parent.apply(new RemoveNestListAction(target));
2403
2541
  }
2404
2542
  else {
2405
- let lastChild = inlineHtml;
2406
- while (lastChild.child &&
2407
- child.parentNode &&
2408
- lastChild.child.htmlTag === child.parentNode.nodeName.toLowerCase()) {
2409
- lastChild = lastChild.child;
2410
- }
2411
- lastChild.child = childInlineHtmlNode;
2543
+ parent.apply(new codeBlock.RemoveChildrenAction(target));
2412
2544
  }
2413
2545
  }
2414
- return inlineHtml ? Object.assign({}, inlineHtml) : null;
2415
2546
  }
2416
2547
  }
2417
- InlineHtmlAnnotationHandler.canHandleTags = [
2418
- 'A',
2419
- 'ABBR',
2420
- 'AUDIO',
2421
- 'B',
2422
- 'BDI',
2423
- 'BDO',
2424
- 'CITE',
2425
- 'CODE',
2426
- 'DEL',
2427
- 'DFN',
2428
- 'EMBED',
2429
- 'EM',
2430
- 'I',
2431
- 'INS',
2432
- 'KBD',
2433
- 'MARK',
2434
- 'METER',
2435
- 'OUTPUT',
2436
- 'PROGRESS',
2437
- 'Q',
2438
- 'S',
2439
- 'SMALL',
2440
- 'SPAN',
2441
- 'STRONG',
2442
- 'SUB',
2443
- 'SUP',
2444
- 'TIME',
2445
- 'U',
2446
- 'VAR',
2447
- 'VIDEO',
2448
- ];
2449
2548
 
2450
- /** Html element to annotations generator */
2451
- class HtmlElementToAnnotationGenerator {
2452
- constructor() {
2453
- this.handlers = [
2454
- new TextAlignAnnotationHandler(),
2455
- new IndentAnnotationHandler(),
2456
- new BoldAnnotationHandler(),
2457
- new ItalicAnnotationHandler(),
2458
- new UnderlineAnnotationHandler(),
2459
- new StrikeThroughAnnotationHandler(),
2460
- new ColorAnnotationHandler(),
2461
- new LinkAnnotationHandler(),
2462
- new CodeAnnotationHandler(),
2463
- new ImageSizeAnnotationHandler(),
2464
- new ImageAltAnnotationHandler(),
2465
- new CustomAttributeAnnotationHandler(),
2466
- new CustomClassAnnotationHandler(),
2467
- new CustomStyleAnnotationHandler(),
2468
- new LinkAnnotationHandler(),
2469
- new TextStyleAnnotationHandler(),
2470
- new InlineHtmlAnnotationHandler(),
2471
- ];
2472
- }
2549
+ /**
2550
+ * Manager class for registering DTO action strategies.
2551
+ */
2552
+ class RTEDTOActionStrategyManager {
2473
2553
  /**
2474
- * The function generates annotations for a given target DTO and HTML element based on a set of
2475
- * strategies.
2554
+ * Registers basic strategies for a given DTO class.
2476
2555
  *
2477
- * @typedef T class name of target DTO
2478
- * @typedef V generated annotations type
2479
- * @param {T} targetDto - Which DTO is the generated annotations to set.
2480
- * @param {HTMLElement} element - Current html element.
2481
- * @param {HtmlElementToAnnotationGenerateOptions} [options] - Options
2482
- * @returns {V} Generated annotations.
2556
+ * @param {string} dtoClassName - The name of the RTE block class name.
2483
2557
  */
2484
- generate(targetDto, element, options = { autoMatchFormat: true }) {
2485
- const isLinkElement = element.tagName === 'A';
2486
- return this.handlers
2487
- .filter((handler) => !options.autoMatchFormat && isLinkElement ? handler instanceof LinkAnnotationHandler : true)
2488
- .filter((handler) => element.nodeType !== Node.TEXT_NODE &&
2489
- handler.canHandle(targetDto, {
2490
- skipCustomAnnotations: options.skipCustomAnnotations || isLinkElement,
2491
- autoMatchFormat: options.autoMatchFormat,
2492
- }))
2493
- .reduce((annotations, handler) => {
2494
- const result = handler.handle(element, options.parentAnnotations);
2495
- return Object.assign(Object.assign({}, annotations), result);
2496
- }, {});
2558
+ registerBlockBasicStrategies(dtoClassName) {
2559
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.DELETE_CHILDREN, dtoClassName, dtoClassName === RTEListBlock.name
2560
+ ? new ListRemoveListItemStrategy()
2561
+ : new codeBlock.RemoveChildrenStrategy());
2562
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.APPEND_CHILDREN, dtoClassName, new AppendChildrenStrategy());
2563
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_CHILDREN_BEFORE, dtoClassName, new InsertChildrenBeforeStrategy());
2564
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_CHILDREN_AFTER, dtoClassName, new InsertChildrenAfterStrategy());
2565
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.DELETE_BLOCK_CONTENT, dtoClassName, new BlockDeleteTextOrDecoratorNodeStrategy());
2566
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_NEW_PARAGRAPH, dtoClassName, dtoClassName === RTEListItemBlock.name
2567
+ ? new ListItemInsertNewParagraphStrategy()
2568
+ : new BlockInsertNewParagraphStrategy());
2569
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_TEXT_TO_DECORATOR_NODE, dtoClassName, new InsertTextToDecoratorNodeStrategy());
2570
+ codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.INSERT_NODE_TO_NEAREST_ROOT, dtoClassName, new InsertNodeToNearestRootStrategy());
2497
2571
  }
2498
2572
  }
2499
- const htmlElementToAnnotationGenerator = new HtmlElementToAnnotationGenerator();
2573
+ const RTEDTOActionStrategyManager$1 = new RTEDTOActionStrategyManager();
2500
2574
 
2501
2575
  /** Abstract class for block html element to RTE block dto */
2502
2576
  class BlockToRTEBlockStrategyAbstract extends ElementToDTOStrategy {
@@ -3607,6 +3681,18 @@ class VegaRTEContent {
3607
3681
  apply(action) {
3608
3682
  codeBlock.ActionHandleStrategyRegistry.executeTheStrategy(action, this);
3609
3683
  }
3684
+ /**
3685
+ * Get the last node in the content.
3686
+ *
3687
+ * @returns {Nullable<RTENode>} The last node in the content or null if there are no nodes.
3688
+ */
3689
+ getLastNode() {
3690
+ if (this.children.length === 0) {
3691
+ return null;
3692
+ }
3693
+ const lastBlock = this.children[this.children.length - 1];
3694
+ return lastBlock.getLastNode();
3695
+ }
3610
3696
  /**
3611
3697
  * Convert text to list.
3612
3698
  *
@@ -3681,12 +3767,72 @@ class VegaRTEContent {
3681
3767
  codeBlock.ActionHandleStrategyRegistry.register(codeBlock.ModifyContentActionType.UPDATE_CURSOR_POSITION, VegaRTEContent.name, new UpdateCursorPositionStrategy());
3682
3768
  })();
3683
3769
 
3770
+ /**
3771
+ * RTEDTORendererManager is a singleton class that manages the registration and retrieval of RTE DTO renderers.
3772
+ */
3773
+ class RTEDTORendererManager {
3774
+ constructor() {
3775
+ // Register RTE DTO renderers, mapping type strings to their respective renderer instances.
3776
+ this.RTE_DTO_RENDERER_MAP = new Map();
3777
+ // Register RTE Toolbar Button Renderers, mapping type strings to their respective renderer instances.
3778
+ this.RTE_TOOLBAR_BUTTON_RENDERER_MAP = new Map();
3779
+ }
3780
+ /**
3781
+ * Registers a new RTE DTO renderer.
3782
+ *
3783
+ * @param {string} type - The type identifier for the RTE DTO renderer.
3784
+ * @param {VegaRTEBaseRenderer} RTEDTORenderer - The renderer instance for the RTE DTO.
3785
+ */
3786
+ registerRTEDTORenderer(type, RTEDTORenderer) {
3787
+ const existRenderer = this.RTE_DTO_RENDERER_MAP.get(type);
3788
+ if (RTEDTORenderer &&
3789
+ existRenderer &&
3790
+ existRenderer.constructor.name !== RTEDTORenderer.constructor.name) {
3791
+ throw new Error(`Renderer for type ${type} is already registered with a different class(${existRenderer.constructor.name}).`);
3792
+ }
3793
+ this.RTE_DTO_RENDERER_MAP.set(type, RTEDTORenderer);
3794
+ }
3795
+ /**
3796
+ * Registers a new RTE Toolbar Button Renderer.
3797
+ *
3798
+ * @param {string} type - The type identifier for the RTE Toolbar Button Renderer.
3799
+ * @param {VegaRTEToolbarButtonRenderer} RTEToolbarButtonRenderer - The renderer instance for the RTE Toolbar Button.
3800
+ */
3801
+ registerRTEToolbarButtonRenderer(type, RTEToolbarButtonRenderer) {
3802
+ this.RTE_TOOLBAR_BUTTON_RENDERER_MAP.set(type, RTEToolbarButtonRenderer);
3803
+ }
3804
+ /**
3805
+ * Retrieves the RTE renderer for a given type.
3806
+ *
3807
+ * @param {string} type - The type identifier for the RTE block.
3808
+ * @returns {Nullable<BaseRenderer>} - The renderer instance for the RTE block, or null if not found.
3809
+ */
3810
+ getRTERenderer(type) {
3811
+ return this.RTE_DTO_RENDERER_MAP.get(type);
3812
+ }
3813
+ /**
3814
+ * Retrieves the RTE Toolbar Button Renderer for a given type.
3815
+ *
3816
+ * @param {string} type - The type identifier for the RTE Toolbar Button Renderer.
3817
+ * @returns {Nullable<VegaRTEToolbarButtonRenderer>} - The renderer instance for the RTE Toolbar Button, or null if not found.
3818
+ */
3819
+ getRTEToolbarButtonRenderer(type) {
3820
+ return this.RTE_TOOLBAR_BUTTON_RENDERER_MAP.get(type);
3821
+ }
3822
+ }
3823
+ const RTEDTORendererManager$1 = new RTEDTORendererManager();
3824
+
3825
+ exports.ElementToDTOClassStrategyManager = ElementToDTOClassStrategyManager;
3826
+ exports.ElementToDTOStrategy = ElementToDTOStrategy;
3684
3827
  exports.ElementToDtoStrategyProcessor = ElementToDtoStrategyProcessor$1;
3685
3828
  exports.ImageAnnotation = ImageAnnotation;
3686
3829
  exports.InsertNewParagraphAction = InsertNewParagraphAction;
3687
3830
  exports.MergeTwoBlocksNodesAction = MergeTwoBlocksNodesAction;
3831
+ exports.RTEDTOActionStrategyManager = RTEDTOActionStrategyManager$1;
3832
+ exports.RTEDTORendererManager = RTEDTORendererManager$1;
3688
3833
  exports.RTEImageBlock = RTEImageBlock;
3689
3834
  exports.RTEImageNode = RTEImageNode;
3690
3835
  exports.RTEListBlock = RTEListBlock;
3691
3836
  exports.RTEListItemBlock = RTEListItemBlock;
3837
+ exports.UpdateCursorPositionAction = UpdateCursorPositionAction;
3692
3838
  exports.VegaRTEContent = VegaRTEContent;