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