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