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