@opentiny/fluent-editor 3.19.0 → 3.19.1-alpha.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/README.md +97 -96
- package/es/config/base64-image.es.js +9 -0
- package/es/config/base64-image.es.js.map +1 -0
- package/es/config/editor.config.es.js +86 -0
- package/es/config/editor.config.es.js.map +1 -0
- package/es/config/editor.utils.es.js +141 -0
- package/es/config/editor.utils.es.js.map +1 -0
- package/es/config/i18n/en-us.es.js +90 -0
- package/es/config/i18n/en-us.es.js.map +1 -0
- package/es/config/i18n/zh-cn.es.js +90 -0
- package/es/config/i18n/zh-cn.es.js.map +1 -0
- package/es/config/icons.config.es.js +301 -0
- package/es/config/icons.config.es.js.map +1 -0
- package/es/config/types/additional-toolbar-item.interface.es.js +2 -0
- package/es/config/types/additional-toolbar-item.interface.es.js.map +1 -0
- package/es/config/types/content-change.interface.es.js +2 -0
- package/es/config/types/content-change.interface.es.js.map +1 -0
- package/es/config/types/content-save.interface.es.js +2 -0
- package/es/config/types/content-save.interface.es.js.map +1 -0
- package/es/config/types/counter-option.interface.es.js +2 -0
- package/es/config/types/counter-option.interface.es.js.map +1 -0
- package/es/config/types/editor-config.interface.es.js +2 -0
- package/es/config/types/editor-config.interface.es.js.map +1 -0
- package/es/config/types/editor-modules.interface.es.js +2 -0
- package/es/config/types/editor-modules.interface.es.js.map +1 -0
- package/es/config/types/file-operation.interface.es.js +2 -0
- package/es/config/types/file-operation.interface.es.js.map +1 -0
- package/es/config/types/focus-change.interface.es.js +2 -0
- package/es/config/types/focus-change.interface.es.js.map +1 -0
- package/es/config/types/fullscreen-module.interface.es.js +2 -0
- package/es/config/types/fullscreen-module.interface.es.js.map +1 -0
- package/es/config/types/help-panel-item.interface.es.js +2 -0
- package/es/config/types/help-panel-item.interface.es.js.map +1 -0
- package/es/config/types/help-panel-option.interface.es.js +2 -0
- package/es/config/types/help-panel-option.interface.es.js.map +1 -0
- package/es/config/types/image-module.interface.es.js +2 -0
- package/es/config/types/image-module.interface.es.js.map +1 -0
- package/es/config/types/image-upload.interface.es.js +2 -0
- package/es/config/types/image-upload.interface.es.js.map +1 -0
- package/es/config/types/index.es.js +23 -0
- package/es/config/types/index.es.js.map +1 -0
- package/es/config/types/load-on-demand-module.interface.es.js +2 -0
- package/es/config/types/load-on-demand-module.interface.es.js.map +1 -0
- package/es/config/types/mention-module.interface.es.js +2 -0
- package/es/config/types/mention-module.interface.es.js.map +1 -0
- package/es/config/types/paste-change.interface.es.js +2 -0
- package/es/config/types/paste-change.interface.es.js.map +1 -0
- package/es/config/types/quick-menu-module.interface.es.js +2 -0
- package/es/config/types/quick-menu-module.interface.es.js.map +1 -0
- package/es/config/types/range.interface.es.js +2 -0
- package/es/config/types/range.interface.es.js.map +1 -0
- package/es/config/types/registry-options.interface.es.js +2 -0
- package/es/config/types/registry-options.interface.es.js.map +1 -0
- package/es/config/types/selection-change.interface.es.js +2 -0
- package/es/config/types/selection-change.interface.es.js.map +1 -0
- package/es/config/types/toolbar-item.interface.es.js +2 -0
- package/es/config/types/toolbar-item.interface.es.js.map +1 -0
- package/es/config/types/type.es.js +2 -0
- package/es/config/types/type.es.js.map +1 -0
- package/es/config/types/validate-error.interface.es.js +2 -0
- package/es/config/types/validate-error.interface.es.js.map +1 -0
- package/es/config.es.js +168 -0
- package/es/config.es.js.map +1 -0
- package/es/counter/index.es.js +60 -0
- package/es/counter/index.es.js.map +1 -0
- package/es/custom-clipboard.es.js +469 -0
- package/es/custom-clipboard.es.js.map +1 -0
- package/es/custom-image/BlotFormatter.es.js +136 -0
- package/es/custom-image/BlotFormatter.es.js.map +1 -0
- package/es/custom-image/Options.es.js +95 -0
- package/es/custom-image/Options.es.js.map +1 -0
- package/es/custom-image/actions/Action.es.js +15 -0
- package/es/custom-image/actions/Action.es.js.map +1 -0
- package/es/custom-image/actions/CustomResizeAction.es.js +158 -0
- package/es/custom-image/actions/CustomResizeAction.es.js.map +1 -0
- package/es/custom-image/actions/DeleteAction.es.js +31 -0
- package/es/custom-image/actions/DeleteAction.es.js.map +1 -0
- package/es/custom-image/image.es.js +95 -0
- package/es/custom-image/image.es.js.map +1 -0
- package/es/custom-image/specs/BlotSpec.es.js +27 -0
- package/es/custom-image/specs/BlotSpec.es.js.map +1 -0
- package/es/custom-image/specs/CustomImageSpec.es.js +117 -0
- package/es/custom-image/specs/CustomImageSpec.es.js.map +1 -0
- package/es/custom-image/specs/ImageSpec.es.js +29 -0
- package/es/custom-image/specs/ImageSpec.es.js.map +1 -0
- package/es/custom-uploader.es.js +161 -0
- package/es/custom-uploader.es.js.map +1 -0
- package/es/emoji/emoji-list/index.es.js +5 -0
- package/es/emoji/emoji-list/index.es.js.map +1 -0
- package/es/emoji/emoji-list/people.es.js +114 -0
- package/es/emoji/emoji-list/people.es.js.map +1 -0
- package/es/emoji/emoji-list.es.js +9 -0
- package/es/emoji/emoji-list.es.js.map +1 -0
- package/es/emoji/emoji-map.es.js +9 -0
- package/es/emoji/emoji-map.es.js.map +1 -0
- package/es/emoji/formats/emoji-blot.es.js +41 -0
- package/es/emoji/formats/emoji-blot.es.js.map +1 -0
- package/es/emoji/index.es.js +8 -0
- package/es/emoji/index.es.js.map +1 -0
- package/es/emoji/modules/emoji.es.js +248 -0
- package/es/emoji/modules/emoji.es.js.map +1 -0
- package/es/emoji/modules/toolbar-emoji.es.js +153 -0
- package/es/emoji/modules/toolbar-emoji.es.js.map +1 -0
- package/es/emoji/utils.es.js +19 -0
- package/es/emoji/utils.es.js.map +1 -0
- package/es/file/formats/file.es.js +56 -0
- package/es/file/formats/file.es.js.map +1 -0
- package/es/file/index.es.js +32 -0
- package/es/file/index.es.js.map +1 -0
- package/es/file/modules/file-bar.es.js +123 -0
- package/es/file/modules/file-bar.es.js.map +1 -0
- package/es/fluent-editor.es.js +163 -0
- package/es/fluent-editor.es.js.map +1 -0
- package/es/format-painter/index.es.js +66 -0
- package/es/format-painter/index.es.js.map +1 -0
- package/es/global-link/constants.es.js +9 -0
- package/es/global-link/constants.es.js.map +1 -0
- package/es/global-link/formats/customer-widget-link.es.js +28 -0
- package/es/global-link/formats/customer-widget-link.es.js.map +1 -0
- package/es/global-link/formats/doc-link.es.js +42 -0
- package/es/global-link/formats/doc-link.es.js.map +1 -0
- package/es/global-link/formats/wiki-link.es.js +34 -0
- package/es/global-link/formats/wiki-link.es.js.map +1 -0
- package/es/global-link/formats/work-item-link.es.js +36 -0
- package/es/global-link/formats/work-item-link.es.js.map +1 -0
- package/es/global-link/global-link-panel.es.js +2 -0
- package/es/global-link/global-link-panel.es.js.map +1 -0
- package/es/global-link/index.es.js +139 -0
- package/es/global-link/index.es.js.map +1 -0
- package/es/global-link/utils/createTable.es.js +50 -0
- package/es/global-link/utils/createTable.es.js.map +1 -0
- package/es/index.es.js +5 -0
- package/es/index.es.js.map +1 -0
- package/es/lineheight.es.js +11 -0
- package/es/lineheight.es.js.map +1 -0
- package/es/link/formats/link.es.js +34 -0
- package/es/link/formats/link.es.js.map +1 -0
- package/es/link/index.es.js +32 -0
- package/es/link/index.es.js.map +1 -0
- package/es/link/modules/tooltip.es.js +275 -0
- package/es/link/modules/tooltip.es.js.map +1 -0
- package/es/mention/Mention.es.js +329 -0
- package/es/mention/Mention.es.js.map +1 -0
- package/es/mention/MentionLink.es.js +37 -0
- package/es/mention/MentionLink.es.js.map +1 -0
- package/es/mention/constants.es.js +9 -0
- package/es/mention/constants.es.js.map +1 -0
- package/es/quick-menu/index.es.js +82 -0
- package/es/quick-menu/index.es.js.map +1 -0
- package/es/screenshot/index.es.js +147 -0
- package/es/screenshot/index.es.js.map +1 -0
- package/es/soft-break/index.es.js +23 -0
- package/es/soft-break/index.es.js.map +1 -0
- package/es/strike/index.es.js +12 -0
- package/es/strike/index.es.js.map +1 -0
- package/es/syntax/index.es.js +30 -0
- package/es/syntax/index.es.js.map +1 -0
- package/es/table/better-table.es.js +434 -0
- package/es/table/better-table.es.js.map +1 -0
- package/es/table/formats/header.es.js +94 -0
- package/es/table/formats/header.es.js.map +1 -0
- package/es/table/formats/list.es.js +163 -0
- package/es/table/formats/list.es.js.map +1 -0
- package/es/table/formats/table.es.js +970 -0
- package/es/table/formats/table.es.js.map +1 -0
- package/es/table/modules/table-column-tool.es.js +400 -0
- package/es/table/modules/table-column-tool.es.js.map +1 -0
- package/es/table/modules/table-operation-menu.es.js +457 -0
- package/es/table/modules/table-operation-menu.es.js.map +1 -0
- package/es/table/modules/table-scroll-bar.es.js +190 -0
- package/es/table/modules/table-scroll-bar.es.js.map +1 -0
- package/es/table/modules/table-selection.es.js +306 -0
- package/es/table/modules/table-selection.es.js.map +1 -0
- package/es/table/table-config.es.js +74 -0
- package/es/table/table-config.es.js.map +1 -0
- package/es/table/utils/index.es.js +54 -0
- package/es/table/utils/index.es.js.map +1 -0
- package/es/table/utils/node-matchers.es.js +292 -0
- package/es/table/utils/node-matchers.es.js.map +1 -0
- package/es/toolbar/better-picker.es.js +307 -0
- package/es/toolbar/better-picker.es.js.map +1 -0
- package/es/toolbar/index.es.js +139 -0
- package/es/toolbar/index.es.js.map +1 -0
- package/es/types/vue.d.es.js +2 -0
- package/es/types/vue.d.es.js.map +1 -0
- package/es/utils/debounce.es.js +112 -0
- package/es/utils/debounce.es.js.map +1 -0
- package/es/utils/method.es.js +68 -0
- package/es/utils/method.es.js.map +1 -0
- package/es/video/index.es.js +49 -0
- package/es/video/index.es.js.map +1 -0
- package/lib/config/base64-image.cjs.js +9 -0
- package/lib/config/base64-image.cjs.js.map +1 -0
- package/lib/config/editor.config.cjs.js +86 -0
- package/lib/config/editor.config.cjs.js.map +1 -0
- package/lib/config/editor.utils.cjs.js +141 -0
- package/lib/config/editor.utils.cjs.js.map +1 -0
- package/lib/config/i18n/en-us.cjs.js +90 -0
- package/lib/config/i18n/en-us.cjs.js.map +1 -0
- package/lib/config/i18n/zh-cn.cjs.js +90 -0
- package/lib/config/i18n/zh-cn.cjs.js.map +1 -0
- package/lib/config/icons.config.cjs.js +301 -0
- package/lib/config/icons.config.cjs.js.map +1 -0
- package/lib/config/types/additional-toolbar-item.interface.cjs.js +2 -0
- package/lib/config/types/additional-toolbar-item.interface.cjs.js.map +1 -0
- package/lib/config/types/content-change.interface.cjs.js +2 -0
- package/lib/config/types/content-change.interface.cjs.js.map +1 -0
- package/lib/config/types/content-save.interface.cjs.js +2 -0
- package/lib/config/types/content-save.interface.cjs.js.map +1 -0
- package/lib/config/types/counter-option.interface.cjs.js +2 -0
- package/lib/config/types/counter-option.interface.cjs.js.map +1 -0
- package/lib/config/types/editor-config.interface.cjs.js +2 -0
- package/lib/config/types/editor-config.interface.cjs.js.map +1 -0
- package/lib/config/types/editor-modules.interface.cjs.js +2 -0
- package/lib/config/types/editor-modules.interface.cjs.js.map +1 -0
- package/lib/config/types/file-operation.interface.cjs.js +2 -0
- package/lib/config/types/file-operation.interface.cjs.js.map +1 -0
- package/lib/config/types/focus-change.interface.cjs.js +2 -0
- package/lib/config/types/focus-change.interface.cjs.js.map +1 -0
- package/lib/config/types/fullscreen-module.interface.cjs.js +2 -0
- package/lib/config/types/fullscreen-module.interface.cjs.js.map +1 -0
- package/lib/config/types/help-panel-item.interface.cjs.js +2 -0
- package/lib/config/types/help-panel-item.interface.cjs.js.map +1 -0
- package/lib/config/types/help-panel-option.interface.cjs.js +2 -0
- package/lib/config/types/help-panel-option.interface.cjs.js.map +1 -0
- package/lib/config/types/image-module.interface.cjs.js +2 -0
- package/lib/config/types/image-module.interface.cjs.js.map +1 -0
- package/lib/config/types/image-upload.interface.cjs.js +2 -0
- package/lib/config/types/image-upload.interface.cjs.js.map +1 -0
- package/lib/config/types/index.cjs.js +24 -0
- package/lib/config/types/index.cjs.js.map +1 -0
- package/lib/config/types/load-on-demand-module.interface.cjs.js +2 -0
- package/lib/config/types/load-on-demand-module.interface.cjs.js.map +1 -0
- package/lib/config/types/mention-module.interface.cjs.js +2 -0
- package/lib/config/types/mention-module.interface.cjs.js.map +1 -0
- package/lib/config/types/paste-change.interface.cjs.js +2 -0
- package/lib/config/types/paste-change.interface.cjs.js.map +1 -0
- package/lib/config/types/quick-menu-module.interface.cjs.js +2 -0
- package/lib/config/types/quick-menu-module.interface.cjs.js.map +1 -0
- package/lib/config/types/range.interface.cjs.js +2 -0
- package/lib/config/types/range.interface.cjs.js.map +1 -0
- package/lib/config/types/registry-options.interface.cjs.js +2 -0
- package/lib/config/types/registry-options.interface.cjs.js.map +1 -0
- package/lib/config/types/selection-change.interface.cjs.js +2 -0
- package/lib/config/types/selection-change.interface.cjs.js.map +1 -0
- package/lib/config/types/toolbar-item.interface.cjs.js +2 -0
- package/lib/config/types/toolbar-item.interface.cjs.js.map +1 -0
- package/lib/config/types/type.cjs.js +2 -0
- package/lib/config/types/type.cjs.js.map +1 -0
- package/lib/config/types/validate-error.interface.cjs.js +2 -0
- package/lib/config/types/validate-error.interface.cjs.js.map +1 -0
- package/lib/config.cjs.js +168 -0
- package/lib/config.cjs.js.map +1 -0
- package/lib/counter/index.cjs.js +60 -0
- package/lib/counter/index.cjs.js.map +1 -0
- package/lib/custom-clipboard.cjs.js +469 -0
- package/lib/custom-clipboard.cjs.js.map +1 -0
- package/lib/custom-image/BlotFormatter.cjs.js +136 -0
- package/lib/custom-image/BlotFormatter.cjs.js.map +1 -0
- package/lib/custom-image/Options.cjs.js +95 -0
- package/lib/custom-image/Options.cjs.js.map +1 -0
- package/lib/custom-image/actions/Action.cjs.js +15 -0
- package/lib/custom-image/actions/Action.cjs.js.map +1 -0
- package/lib/custom-image/actions/CustomResizeAction.cjs.js +158 -0
- package/lib/custom-image/actions/CustomResizeAction.cjs.js.map +1 -0
- package/lib/custom-image/actions/DeleteAction.cjs.js +31 -0
- package/lib/custom-image/actions/DeleteAction.cjs.js.map +1 -0
- package/lib/custom-image/image.cjs.js +95 -0
- package/lib/custom-image/image.cjs.js.map +1 -0
- package/lib/custom-image/specs/BlotSpec.cjs.js +27 -0
- package/lib/custom-image/specs/BlotSpec.cjs.js.map +1 -0
- package/lib/custom-image/specs/CustomImageSpec.cjs.js +117 -0
- package/lib/custom-image/specs/CustomImageSpec.cjs.js.map +1 -0
- package/lib/custom-image/specs/ImageSpec.cjs.js +29 -0
- package/lib/custom-image/specs/ImageSpec.cjs.js.map +1 -0
- package/lib/custom-uploader.cjs.js +161 -0
- package/lib/custom-uploader.cjs.js.map +1 -0
- package/lib/emoji/emoji-list/index.cjs.js +5 -0
- package/lib/emoji/emoji-list/index.cjs.js.map +1 -0
- package/lib/emoji/emoji-list/people.cjs.js +114 -0
- package/lib/emoji/emoji-list/people.cjs.js.map +1 -0
- package/lib/emoji/emoji-list.cjs.js +9 -0
- package/lib/emoji/emoji-list.cjs.js.map +1 -0
- package/lib/emoji/emoji-map.cjs.js +9 -0
- package/lib/emoji/emoji-map.cjs.js.map +1 -0
- package/lib/emoji/formats/emoji-blot.cjs.js +41 -0
- package/lib/emoji/formats/emoji-blot.cjs.js.map +1 -0
- package/lib/emoji/index.cjs.js +8 -0
- package/lib/emoji/index.cjs.js.map +1 -0
- package/lib/emoji/modules/emoji.cjs.js +248 -0
- package/lib/emoji/modules/emoji.cjs.js.map +1 -0
- package/lib/emoji/modules/toolbar-emoji.cjs.js +153 -0
- package/lib/emoji/modules/toolbar-emoji.cjs.js.map +1 -0
- package/lib/emoji/utils.cjs.js +19 -0
- package/lib/emoji/utils.cjs.js.map +1 -0
- package/lib/file/formats/file.cjs.js +56 -0
- package/lib/file/formats/file.cjs.js.map +1 -0
- package/lib/file/index.cjs.js +32 -0
- package/lib/file/index.cjs.js.map +1 -0
- package/lib/file/modules/file-bar.cjs.js +123 -0
- package/lib/file/modules/file-bar.cjs.js.map +1 -0
- package/lib/fluent-editor.cjs.js +163 -0
- package/lib/fluent-editor.cjs.js.map +1 -0
- package/lib/format-painter/index.cjs.js +66 -0
- package/lib/format-painter/index.cjs.js.map +1 -0
- package/lib/global-link/constants.cjs.js +9 -0
- package/lib/global-link/constants.cjs.js.map +1 -0
- package/lib/global-link/formats/customer-widget-link.cjs.js +28 -0
- package/lib/global-link/formats/customer-widget-link.cjs.js.map +1 -0
- package/lib/global-link/formats/doc-link.cjs.js +42 -0
- package/lib/global-link/formats/doc-link.cjs.js.map +1 -0
- package/lib/global-link/formats/wiki-link.cjs.js +34 -0
- package/lib/global-link/formats/wiki-link.cjs.js.map +1 -0
- package/lib/global-link/formats/work-item-link.cjs.js +36 -0
- package/lib/global-link/formats/work-item-link.cjs.js.map +1 -0
- package/lib/global-link/global-link-panel.cjs.js +2 -0
- package/lib/global-link/global-link-panel.cjs.js.map +1 -0
- package/lib/global-link/index.cjs.js +139 -0
- package/lib/global-link/index.cjs.js.map +1 -0
- package/lib/global-link/utils/createTable.cjs.js +50 -0
- package/lib/global-link/utils/createTable.cjs.js.map +1 -0
- package/lib/index.cjs.js +5 -0
- package/lib/index.cjs.js.map +1 -0
- package/lib/lineheight.cjs.js +11 -0
- package/lib/lineheight.cjs.js.map +1 -0
- package/lib/link/formats/link.cjs.js +34 -0
- package/lib/link/formats/link.cjs.js.map +1 -0
- package/lib/link/index.cjs.js +32 -0
- package/lib/link/index.cjs.js.map +1 -0
- package/lib/link/modules/tooltip.cjs.js +275 -0
- package/lib/link/modules/tooltip.cjs.js.map +1 -0
- package/lib/mention/Mention.cjs.js +329 -0
- package/lib/mention/Mention.cjs.js.map +1 -0
- package/lib/mention/MentionLink.cjs.js +37 -0
- package/lib/mention/MentionLink.cjs.js.map +1 -0
- package/lib/mention/constants.cjs.js +9 -0
- package/lib/mention/constants.cjs.js.map +1 -0
- package/lib/quick-menu/index.cjs.js +82 -0
- package/lib/quick-menu/index.cjs.js.map +1 -0
- package/lib/screenshot/index.cjs.js +147 -0
- package/lib/screenshot/index.cjs.js.map +1 -0
- package/lib/soft-break/index.cjs.js +23 -0
- package/lib/soft-break/index.cjs.js.map +1 -0
- package/lib/strike/index.cjs.js +12 -0
- package/lib/strike/index.cjs.js.map +1 -0
- package/lib/syntax/index.cjs.js +30 -0
- package/lib/syntax/index.cjs.js.map +1 -0
- package/lib/table/better-table.cjs.js +434 -0
- package/lib/table/better-table.cjs.js.map +1 -0
- package/lib/table/formats/header.cjs.js +94 -0
- package/lib/table/formats/header.cjs.js.map +1 -0
- package/lib/table/formats/list.cjs.js +163 -0
- package/lib/table/formats/list.cjs.js.map +1 -0
- package/lib/table/formats/table.cjs.js +970 -0
- package/lib/table/formats/table.cjs.js.map +1 -0
- package/lib/table/modules/table-column-tool.cjs.js +400 -0
- package/lib/table/modules/table-column-tool.cjs.js.map +1 -0
- package/lib/table/modules/table-operation-menu.cjs.js +457 -0
- package/lib/table/modules/table-operation-menu.cjs.js.map +1 -0
- package/lib/table/modules/table-scroll-bar.cjs.js +190 -0
- package/lib/table/modules/table-scroll-bar.cjs.js.map +1 -0
- package/lib/table/modules/table-selection.cjs.js +306 -0
- package/lib/table/modules/table-selection.cjs.js.map +1 -0
- package/lib/table/table-config.cjs.js +74 -0
- package/lib/table/table-config.cjs.js.map +1 -0
- package/lib/table/utils/index.cjs.js +54 -0
- package/lib/table/utils/index.cjs.js.map +1 -0
- package/lib/table/utils/node-matchers.cjs.js +292 -0
- package/lib/table/utils/node-matchers.cjs.js.map +1 -0
- package/lib/toolbar/better-picker.cjs.js +308 -0
- package/lib/toolbar/better-picker.cjs.js.map +1 -0
- package/lib/toolbar/index.cjs.js +139 -0
- package/lib/toolbar/index.cjs.js.map +1 -0
- package/lib/types/vue.d.cjs.js +2 -0
- package/lib/types/vue.d.cjs.js.map +1 -0
- package/lib/utils/debounce.cjs.js +112 -0
- package/lib/utils/debounce.cjs.js.map +1 -0
- package/lib/utils/method.cjs.js +68 -0
- package/lib/utils/method.cjs.js.map +1 -0
- package/lib/video/index.cjs.js +49 -0
- package/lib/video/index.cjs.js.map +1 -0
- package/package.json +63 -65
- package/theme/index.css +4742 -0
- package/index.cjs.js +0 -374
- package/index.cjs.js.map +0 -1
- package/index.es.js +0 -51095
- package/index.es.js.map +0 -1
- package/style.css +0 -7
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import Quill from "quill";
|
|
2
|
+
import { ERROR_IMAGE_PLACEHOLDER_EN, ERROR_IMAGE_PLACEHOLDER_CN } from "./config/base64-image.es.js";
|
|
3
|
+
import { BIG_DELTA_LIMIT, LANG_CONF } from "./config/editor.config.es.js";
|
|
4
|
+
import { isNullOrUndefined, insideTable, replaceDeltaImage, imageFileToUrl, imageUrlToFile, splitWithBreak, omit, hexToRgbA } from "./config/editor.utils.es.js";
|
|
5
|
+
const Clipboard = Quill.imports["modules/clipboard"];
|
|
6
|
+
const Delta = Quill.imports["delta"];
|
|
7
|
+
class CustomClipboard extends Clipboard {
|
|
8
|
+
prepareMatching(container, nodeMatches) {
|
|
9
|
+
const elementMatchers = [];
|
|
10
|
+
const textMatchers = [];
|
|
11
|
+
this.matchers.forEach((pair) => {
|
|
12
|
+
const [selector, matcher] = pair;
|
|
13
|
+
switch (selector) {
|
|
14
|
+
case Node.TEXT_NODE:
|
|
15
|
+
textMatchers.push(matcher);
|
|
16
|
+
break;
|
|
17
|
+
case Node.ELEMENT_NODE:
|
|
18
|
+
elementMatchers.push(matcher);
|
|
19
|
+
break;
|
|
20
|
+
default: {
|
|
21
|
+
const vRegex = /v:(.+)/;
|
|
22
|
+
const nodeList = vRegex.test(selector) ? Array.from(container.getElementsByTagName(selector)) : Array.from(container.querySelectorAll(selector));
|
|
23
|
+
nodeList.forEach((node) => {
|
|
24
|
+
if (nodeMatches.has(node)) {
|
|
25
|
+
const matches = nodeMatches.get(node);
|
|
26
|
+
matches.push(matcher);
|
|
27
|
+
} else {
|
|
28
|
+
nodeMatches.set(node, [matcher]);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return [elementMatchers, textMatchers];
|
|
36
|
+
}
|
|
37
|
+
onCaptureCopy(e, isCut = false) {
|
|
38
|
+
if (e.defaultPrevented) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
const [range] = this.quill.selection.getRange();
|
|
43
|
+
if (isNullOrUndefined(range)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const { html, text } = this.onCopy(range, isCut);
|
|
47
|
+
if (!e.clipboardData) {
|
|
48
|
+
e.clipboardData = {
|
|
49
|
+
types: "text/plain",
|
|
50
|
+
setData: (_type, value) => {
|
|
51
|
+
return window["clipboardData"].setData("Text", value);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
let plainText = text;
|
|
56
|
+
if (html.startsWith("<pre>")) {
|
|
57
|
+
plainText = text.replace(/\u00A0/g, " ");
|
|
58
|
+
}
|
|
59
|
+
e.clipboardData.setData("text/html", html);
|
|
60
|
+
e.clipboardData.setData("text/plain", plainText);
|
|
61
|
+
if (isCut) {
|
|
62
|
+
this.quill.deleteText(range, Quill.sources.USER);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
onCapturePaste(e) {
|
|
66
|
+
if (e.defaultPrevented || !this.quill.isEnabled()) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
e.preventDefault();
|
|
70
|
+
const range = this.quill.getSelection(true);
|
|
71
|
+
if (isNullOrUndefined(range)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (!e.clipboardData) {
|
|
75
|
+
e.clipboardData = {
|
|
76
|
+
types: "text/plain",
|
|
77
|
+
getData: () => {
|
|
78
|
+
return window["clipboardData"].getData("Text");
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const html = e.clipboardData.getData("text/html");
|
|
83
|
+
const text = e.clipboardData.getData("text/plain");
|
|
84
|
+
const files = Array.from(e.clipboardData.files || []);
|
|
85
|
+
const msExcelCheck = /<meta.*?Microsoft Excel\s[\d].*?>/;
|
|
86
|
+
if (html.search(msExcelCheck) === -1 && files.length > 0) {
|
|
87
|
+
this.quill.uploader.upload(range, files);
|
|
88
|
+
} else {
|
|
89
|
+
const msWordCheck1 = /<meta\s*name="?generator"?\s*content="?microsoft\s*word\s*\d+"?\/?>/i;
|
|
90
|
+
const msWordCheck2 = /xmlns:o="urn:schemas-microsoft-com/i;
|
|
91
|
+
const result = { html, text, files, rtf: null };
|
|
92
|
+
if (html.search(msExcelCheck) !== -1) {
|
|
93
|
+
result.html = renderStyles(html);
|
|
94
|
+
}
|
|
95
|
+
if (msWordCheck1.test(html) || msWordCheck2.test(html)) {
|
|
96
|
+
result.rtf = e.clipboardData.getData("text/rtf");
|
|
97
|
+
}
|
|
98
|
+
this.onPaste(range, result);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
onPaste(range, { html, text, files: clipboardFiles, rtf }) {
|
|
102
|
+
const hexImages = this.extractImageDataFromRtf(rtf);
|
|
103
|
+
const rootBgColor = getComputedStyle(this.quill.root)["backgroundColor"];
|
|
104
|
+
const formats = this.quill.getFormat(range.index);
|
|
105
|
+
let pastedDelta = this.convert({ text, html }, formats);
|
|
106
|
+
pastedDelta = replaceDeltaWhiteSpace(pastedDelta, rootBgColor);
|
|
107
|
+
const deltaLength = pastedDelta.ops.length;
|
|
108
|
+
let loadingTipsContainer;
|
|
109
|
+
if (deltaLength > BIG_DELTA_LIMIT) {
|
|
110
|
+
loadingTipsContainer = this.quill.addContainer("ql-loading-tips");
|
|
111
|
+
loadingTipsContainer.innerHTML = LANG_CONF["pasting"];
|
|
112
|
+
}
|
|
113
|
+
const linePos = { index: range.index, length: range.length, fix: 0 };
|
|
114
|
+
const [line, offset] = this.quill.getLine(range.index);
|
|
115
|
+
const isInsideTable = insideTable.call(this);
|
|
116
|
+
const handlePasteContent = (content) => {
|
|
117
|
+
let pastedContent = content;
|
|
118
|
+
const tableBreaker = pastedContent.ops.find((op) => {
|
|
119
|
+
return op.attributes && (op.attributes["blockquote"] || op.attributes["code-block"]);
|
|
120
|
+
});
|
|
121
|
+
if (isInsideTable) {
|
|
122
|
+
const table = line.domNode.closest("table.quill-better-table");
|
|
123
|
+
const tableBlot = Quill.find(table);
|
|
124
|
+
const tableIndex = this.quill.getIndex(tableBlot);
|
|
125
|
+
const tableLength = tableBlot.length();
|
|
126
|
+
const tableEndPos = tableIndex + tableLength;
|
|
127
|
+
const anchorNode = getSelection().anchorNode;
|
|
128
|
+
if (tableBreaker) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (formats["table-col"]) {
|
|
132
|
+
linePos.index = tableIndex - 1;
|
|
133
|
+
linePos.length = 0;
|
|
134
|
+
} else if (range.index === tableEndPos - 1 && anchorNode instanceof HTMLDivElement && anchorNode.classList.contains("quill-better-table-wrapper")) {
|
|
135
|
+
const list = pastedContent.filter(
|
|
136
|
+
(op) => op.attributes && op.attributes["list"]
|
|
137
|
+
);
|
|
138
|
+
if (list && list.length) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
linePos.index = tableEndPos;
|
|
142
|
+
linePos.length = 0;
|
|
143
|
+
} else {
|
|
144
|
+
if (!formats["table-cell-line"]) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
pastedContent = {
|
|
148
|
+
ops: pastedContent.filter((op, index) => {
|
|
149
|
+
const regexp = /^[\n\r]+$/;
|
|
150
|
+
const isString = op.insert && typeof op.insert === "string";
|
|
151
|
+
const isLine = isString && regexp.test(op.insert);
|
|
152
|
+
const isCellLine = isLine && op.attributes && op.attributes["table-cell-line"];
|
|
153
|
+
const isList = isLine && op.attributes && op.attributes["list"];
|
|
154
|
+
const isPureLine = isLine && !isCellLine && !isList;
|
|
155
|
+
const isTableCol = isLine && op.attributes && op.attributes["table-col"];
|
|
156
|
+
const isLastCellLine = isCellLine && index === deltaLength - 1;
|
|
157
|
+
return !isPureLine && !isTableCol && !isLastCellLine;
|
|
158
|
+
})
|
|
159
|
+
};
|
|
160
|
+
pastedContent = rebuildDelta(
|
|
161
|
+
new Delta(pastedContent.ops),
|
|
162
|
+
formats["table-cell-line"]
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const lastChild = pastedContent.ops[pastedContent.ops.length - 1];
|
|
167
|
+
const hasList = lastChild && lastChild.attributes && lastChild.attributes["list"];
|
|
168
|
+
if (hasList && offset === 0 && line && line.cache.length === 1 && (line.statics.blotName === "block" || line.statics.blotName === "table-cell-line") && (!line.next || line.next.statics.blotName !== "table-view")) {
|
|
169
|
+
linePos.index = this.quill.getIndex(line);
|
|
170
|
+
linePos.length = line.length();
|
|
171
|
+
linePos.fix = 1;
|
|
172
|
+
}
|
|
173
|
+
const oldDelta = new Delta().retain(linePos.index).delete(linePos.length);
|
|
174
|
+
const delta = oldDelta.concat(pastedContent);
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
this.quill.updateContents(delta, Quill.sources.USER);
|
|
177
|
+
this.quill.setSelection(
|
|
178
|
+
delta.length() - linePos.length - linePos.fix,
|
|
179
|
+
Quill.sources.SILENT
|
|
180
|
+
);
|
|
181
|
+
this.quill.scrollIntoView();
|
|
182
|
+
if (loadingTipsContainer) {
|
|
183
|
+
loadingTipsContainer.remove();
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
(async () => {
|
|
188
|
+
try {
|
|
189
|
+
const [files, placeholders, originalUrls, imageIndexs] = this.flipFilesArray(
|
|
190
|
+
await this.extractFilesFromDelta(
|
|
191
|
+
pastedDelta,
|
|
192
|
+
clipboardFiles,
|
|
193
|
+
hexImages
|
|
194
|
+
)
|
|
195
|
+
);
|
|
196
|
+
if (files.length === 0) {
|
|
197
|
+
handlePasteContent(pastedDelta);
|
|
198
|
+
} else {
|
|
199
|
+
if (this.quill.options.editorPaste && this.quill.options.editorPaste.observers.length !== 0) {
|
|
200
|
+
this.quill.options.editorPaste.emit({
|
|
201
|
+
files,
|
|
202
|
+
callback: ({ code, message, data }) => {
|
|
203
|
+
if (code === 0) {
|
|
204
|
+
const { imageUrls } = data;
|
|
205
|
+
pastedDelta = replaceDeltaImage(
|
|
206
|
+
pastedDelta,
|
|
207
|
+
imageUrls,
|
|
208
|
+
placeholders
|
|
209
|
+
);
|
|
210
|
+
handlePasteContent(pastedDelta);
|
|
211
|
+
} else {
|
|
212
|
+
console.error("error message:", message);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
} else {
|
|
217
|
+
if (files[0] !== void 0 || originalUrls.length === 0) {
|
|
218
|
+
const imageUrls = await this.files2urls(
|
|
219
|
+
files,
|
|
220
|
+
placeholders,
|
|
221
|
+
originalUrls,
|
|
222
|
+
pastedDelta,
|
|
223
|
+
imageIndexs
|
|
224
|
+
);
|
|
225
|
+
pastedDelta = replaceDeltaImage(
|
|
226
|
+
pastedDelta,
|
|
227
|
+
imageUrls,
|
|
228
|
+
placeholders
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
handlePasteContent(pastedDelta);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} catch (_e) {
|
|
235
|
+
throw new Error("Paste failed.");
|
|
236
|
+
}
|
|
237
|
+
})();
|
|
238
|
+
}
|
|
239
|
+
files2urls(files, placeholders, originalUrls, pastedDelta, imageIndexs) {
|
|
240
|
+
return Promise.all(
|
|
241
|
+
files.map((imageFile, index) => {
|
|
242
|
+
const netImgExp = /^((http|https)\:)?\/\/([\s\S]+)$/;
|
|
243
|
+
if (!placeholders[index] && originalUrls[index] && netImgExp.test(originalUrls[index])) {
|
|
244
|
+
return new Promise((resolve) => {
|
|
245
|
+
resolve(originalUrls[index]);
|
|
246
|
+
});
|
|
247
|
+
} else if (this.quill.options.uploadOption.imageUploadToServer) {
|
|
248
|
+
const range = this.getImgSelection(pastedDelta, imageIndexs[index]);
|
|
249
|
+
this.quill.uploader.upload(range, [imageFile]);
|
|
250
|
+
} else {
|
|
251
|
+
return imageFileToUrl(imageFile);
|
|
252
|
+
}
|
|
253
|
+
})
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
flipFilesArray(filesArr) {
|
|
257
|
+
const files = [];
|
|
258
|
+
const placeholders = [];
|
|
259
|
+
const originalUrls = [];
|
|
260
|
+
const imageIndexs = [];
|
|
261
|
+
filesArr.forEach((item) => {
|
|
262
|
+
if (item) {
|
|
263
|
+
const [file, placeholder, originalUrl, imageIndex] = item;
|
|
264
|
+
files.push(file);
|
|
265
|
+
placeholders.push(placeholder);
|
|
266
|
+
originalUrls.push(originalUrl);
|
|
267
|
+
if (imageIndex === 0 || imageIndex) {
|
|
268
|
+
imageIndexs.push(imageIndex);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
return [files, placeholders, originalUrls, imageIndexs];
|
|
273
|
+
}
|
|
274
|
+
// 将图片从hex转为base64
|
|
275
|
+
convertHexToBase64(hexString) {
|
|
276
|
+
return btoa(
|
|
277
|
+
hexString.match(/\w{2}/g).map((char) => {
|
|
278
|
+
return String.fromCharCode(parseInt(char, 16));
|
|
279
|
+
}).join("")
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
// 匹配rtf中的图片,存储为{hex, type}对象数组
|
|
283
|
+
extractImageDataFromRtf(rtfData) {
|
|
284
|
+
if (!rtfData) {
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
const regexPictureHeader = /{\\pict[\s\S]+?\\bliptag-?\d+(\\blipupi-?\d+)?({\\\*\\blipuid\s?[\da-fA-F]+)?[\s}]*?/;
|
|
288
|
+
const regexPicture = new RegExp(
|
|
289
|
+
"(?:(" + regexPictureHeader.source + "))([\\da-fA-F\\s]+)\\}",
|
|
290
|
+
"g"
|
|
291
|
+
);
|
|
292
|
+
const images = rtfData.match(regexPicture);
|
|
293
|
+
const result = [];
|
|
294
|
+
if (images) {
|
|
295
|
+
for (const image of images) {
|
|
296
|
+
let imageType = "";
|
|
297
|
+
if (image.includes("\\pngblip")) {
|
|
298
|
+
imageType = "image/png";
|
|
299
|
+
} else if (image.includes("\\jpegblip")) {
|
|
300
|
+
imageType = "image/jpeg";
|
|
301
|
+
}
|
|
302
|
+
if (imageType) {
|
|
303
|
+
result.push({
|
|
304
|
+
hex: image.replace(regexPictureHeader, "").replace(/[^\da-fA-F]/g, ""),
|
|
305
|
+
type: imageType
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
extractFilesFromDelta(delta, clipboardFiles, hexImages) {
|
|
313
|
+
let index = -1;
|
|
314
|
+
return Promise.all(
|
|
315
|
+
delta.map(async (op) => {
|
|
316
|
+
var _a;
|
|
317
|
+
index++;
|
|
318
|
+
const image = op.insert.image;
|
|
319
|
+
if (!image || image.hasExisted) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
let file;
|
|
323
|
+
let isPlaceholderImage = false;
|
|
324
|
+
let imageIndex;
|
|
325
|
+
try {
|
|
326
|
+
const hexImage = hexImages.length && hexImages.shift();
|
|
327
|
+
const newImage = hexImage && `data:${hexImage.type};base64,${this.convertHexToBase64(
|
|
328
|
+
hexImage.hex
|
|
329
|
+
)}`;
|
|
330
|
+
imageIndex = index;
|
|
331
|
+
file = await imageUrlToFile(newImage || image.src || image);
|
|
332
|
+
} catch (_err) {
|
|
333
|
+
if (clipboardFiles.length !== 0) {
|
|
334
|
+
const clipboardFile = clipboardFiles[0];
|
|
335
|
+
const imageType = ((_a = clipboardFile.type) == null ? void 0 : _a.indexOf("image")) === -1 ? "image/png" : clipboardFile.type;
|
|
336
|
+
const blob = clipboardFile.slice(0, clipboardFile.size, imageType);
|
|
337
|
+
file = new File([blob], `image-CORS-${(/* @__PURE__ */ new Date()).getTime()}.png`, {
|
|
338
|
+
type: imageType
|
|
339
|
+
});
|
|
340
|
+
} else if (image.src.startsWith("http")) {
|
|
341
|
+
} else {
|
|
342
|
+
const errorImagePlaceholderJpg = LANG_CONF["img-error"] === "Image Copy Error" ? ERROR_IMAGE_PLACEHOLDER_EN : ERROR_IMAGE_PLACEHOLDER_CN;
|
|
343
|
+
file = await imageUrlToFile(errorImagePlaceholderJpg, true);
|
|
344
|
+
isPlaceholderImage = true;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return [file, isPlaceholderImage, image, imageIndex];
|
|
348
|
+
})
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
getImgSelection(delta, imageIndex) {
|
|
352
|
+
let length = 0;
|
|
353
|
+
delta.ops.every((op, index) => {
|
|
354
|
+
if (index === imageIndex) {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
if (typeof op.insert === "string") {
|
|
358
|
+
length += op.insert.length;
|
|
359
|
+
}
|
|
360
|
+
return true;
|
|
361
|
+
});
|
|
362
|
+
const range = {
|
|
363
|
+
index: length,
|
|
364
|
+
length: 0
|
|
365
|
+
};
|
|
366
|
+
return range;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function rebuildDelta(delta, cellLine) {
|
|
370
|
+
const { cell: cellId, colspan, row: rowId, rowspan } = cellLine;
|
|
371
|
+
const buildedDelta = delta.reduce((newDelta, op) => {
|
|
372
|
+
if (op.insert && typeof op.insert === "string") {
|
|
373
|
+
const lines = splitWithBreak(op.insert);
|
|
374
|
+
lines.forEach((text) => {
|
|
375
|
+
if (text === "\n") {
|
|
376
|
+
newDelta.insert("\n", {
|
|
377
|
+
...op.attributes,
|
|
378
|
+
"table-cell-line": { row: rowId, cell: cellId, rowspan, colspan }
|
|
379
|
+
});
|
|
380
|
+
} else {
|
|
381
|
+
text = text.endsWith("\r") ? text.slice(0, -1) : text;
|
|
382
|
+
newDelta.insert(
|
|
383
|
+
text,
|
|
384
|
+
omit(op.attributes, ["table", "table-cell-line"])
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
} else {
|
|
389
|
+
newDelta.insert(op.insert, op.attributes);
|
|
390
|
+
}
|
|
391
|
+
return newDelta;
|
|
392
|
+
}, new Delta());
|
|
393
|
+
return buildedDelta;
|
|
394
|
+
}
|
|
395
|
+
function replaceStrWhiteSpace(str) {
|
|
396
|
+
const isWhiteSpace = (value) => /^(\u3000|\u0020){1}$/.test(value);
|
|
397
|
+
let textWithWhiteSpace = "";
|
|
398
|
+
let beginHasChar = false;
|
|
399
|
+
for (const char of str) {
|
|
400
|
+
if (isWhiteSpace(char) && !beginHasChar) {
|
|
401
|
+
textWithWhiteSpace += " ";
|
|
402
|
+
} else {
|
|
403
|
+
textWithWhiteSpace += char;
|
|
404
|
+
beginHasChar = true;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return textWithWhiteSpace;
|
|
408
|
+
}
|
|
409
|
+
function replaceDeltaWhiteSpace(delta, rootBgColor) {
|
|
410
|
+
return delta.reduce((newDelta, op) => {
|
|
411
|
+
if (rootBgColor && op.attributes && op.attributes.color && !op.attributes.background) {
|
|
412
|
+
const originColor = op.attributes.color;
|
|
413
|
+
const fontColor = originColor.indexOf("#") === 0 ? hexToRgbA(originColor) : originColor;
|
|
414
|
+
if (fontColor === rootBgColor || fontColor === "rgba(255,255,255,1)" && rootBgColor === "rgba(0, 0, 0, 0)") {
|
|
415
|
+
delete op.attributes.color;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (op.insert && typeof op.insert === "string") {
|
|
419
|
+
const lines = splitWithBreak(op.insert);
|
|
420
|
+
let insertWithWhiteSpace = "";
|
|
421
|
+
lines.forEach((text) => {
|
|
422
|
+
insertWithWhiteSpace += replaceStrWhiteSpace(text);
|
|
423
|
+
});
|
|
424
|
+
newDelta.insert(insertWithWhiteSpace, op.attributes);
|
|
425
|
+
} else {
|
|
426
|
+
newDelta.insert(op.insert, op.attributes);
|
|
427
|
+
}
|
|
428
|
+
return newDelta;
|
|
429
|
+
}, new Delta());
|
|
430
|
+
}
|
|
431
|
+
function renderStyles(html) {
|
|
432
|
+
let htmlString = html;
|
|
433
|
+
htmlString = htmlString.substring(
|
|
434
|
+
htmlString.indexOf("<html "),
|
|
435
|
+
htmlString.length
|
|
436
|
+
);
|
|
437
|
+
htmlString = htmlString.substring(
|
|
438
|
+
0,
|
|
439
|
+
htmlString.lastIndexOf("</html>") + "</html>".length
|
|
440
|
+
);
|
|
441
|
+
const iframe = document.createElement("iframe");
|
|
442
|
+
iframe.style.display = "none";
|
|
443
|
+
document.body.appendChild(iframe);
|
|
444
|
+
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
|
445
|
+
iframeDoc.open();
|
|
446
|
+
iframeDoc.write(htmlString);
|
|
447
|
+
iframeDoc.close();
|
|
448
|
+
let collection;
|
|
449
|
+
let pointer;
|
|
450
|
+
const rules = iframeDoc.styleSheets[iframeDoc.styleSheets.length - 1]["cssRules"];
|
|
451
|
+
for (let idx = 0; idx < rules.length; idx++) {
|
|
452
|
+
if (rules[idx].selectorText === "") {
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
collection = iframeDoc.body.querySelectorAll(
|
|
456
|
+
rules[idx].selectorText
|
|
457
|
+
);
|
|
458
|
+
for (pointer = 0; pointer < collection.length; pointer++) {
|
|
459
|
+
collection[pointer].style.cssText += rules[idx].style.cssText;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
const convertedString = iframeDoc.firstChild["outerHTML"];
|
|
463
|
+
iframe.parentNode.removeChild(iframe);
|
|
464
|
+
return convertedString;
|
|
465
|
+
}
|
|
466
|
+
export {
|
|
467
|
+
CustomClipboard as default
|
|
468
|
+
};
|
|
469
|
+
//# sourceMappingURL=custom-clipboard.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-clipboard.es.js","sources":["../../src/custom-clipboard.ts"],"sourcesContent":["import Quill from 'quill'\r\nimport {\r\n ERROR_IMAGE_PLACEHOLDER_CN,\r\n ERROR_IMAGE_PLACEHOLDER_EN,\r\n} from './config/base64-image'\r\nimport { BIG_DELTA_LIMIT, LANG_CONF } from './config/editor.config'\r\nimport {\r\n hexToRgbA,\r\n imageFileToUrl,\r\n imageUrlToFile,\r\n insideTable,\r\n isNullOrUndefined,\r\n omit,\r\n replaceDeltaImage,\r\n splitWithBreak,\r\n} from './config/editor.utils'\r\n\r\nconst Clipboard = Quill.imports['modules/clipboard']\r\nconst Delta = Quill.imports['delta']\r\n\r\nclass CustomClipboard extends Clipboard {\r\n quill\r\n convert\r\n onCopy\r\n matchers\r\n\r\n prepareMatching(container, nodeMatches) {\r\n const elementMatchers = []\r\n const textMatchers = []\r\n this.matchers.forEach((pair) => {\r\n const [selector, matcher] = pair\r\n switch (selector) {\r\n case Node.TEXT_NODE:\r\n textMatchers.push(matcher)\r\n break\r\n case Node.ELEMENT_NODE:\r\n elementMatchers.push(matcher)\r\n break\r\n default: {\r\n // word 的 v:shape 系列标签只能通过 getElementsByTagName 获取\r\n const vRegex = /v:(.+)/\r\n const nodeList = vRegex.test(selector)\r\n ? Array.from(container.getElementsByTagName(selector))\r\n : Array.from(container.querySelectorAll(selector))\r\n nodeList.forEach((node) => {\r\n if (nodeMatches.has(node)) {\r\n const matches = nodeMatches.get(node)\r\n matches.push(matcher)\r\n }\r\n else {\r\n nodeMatches.set(node, [matcher])\r\n }\r\n })\r\n break\r\n }\r\n }\r\n })\r\n return [elementMatchers, textMatchers]\r\n }\r\n\r\n onCaptureCopy(e, isCut = false) {\r\n if (e.defaultPrevented) {\r\n return\r\n }\r\n e.preventDefault()\r\n const [range] = this.quill.selection.getRange()\r\n if (isNullOrUndefined(range)) {\r\n return\r\n }\r\n const { html, text } = this.onCopy(range, isCut)\r\n\r\n // 兼容IE11浏览器`\r\n if (!e.clipboardData) {\r\n e.clipboardData = {\r\n types: 'text/plain',\r\n setData: (_type, value) => {\r\n return window['clipboardData'].setData('Text', value)\r\n },\r\n }\r\n }\r\n\r\n // 复制代码时移除utf8中产生的不间断空格\\u00A0\r\n let plainText = text\r\n if (html.startsWith('<pre>')) {\r\n plainText = text.replace(/\\u00A0/g, ' ')\r\n }\r\n\r\n e.clipboardData.setData('text/html', html)\r\n e.clipboardData.setData('text/plain', plainText)\r\n if (isCut) {\r\n this.quill.deleteText(range, Quill.sources.USER)\r\n }\r\n }\r\n\r\n onCapturePaste(e) {\r\n if (e.defaultPrevented || !this.quill.isEnabled()) {\r\n return\r\n }\r\n e.preventDefault()\r\n const range = this.quill.getSelection(true)\r\n if (isNullOrUndefined(range)) {\r\n return\r\n }\r\n\r\n // 兼容IE11浏览器\r\n if (!e.clipboardData) {\r\n e.clipboardData = {\r\n types: 'text/plain',\r\n getData: () => {\r\n return window['clipboardData'].getData('Text')\r\n },\r\n }\r\n }\r\n\r\n const html = e.clipboardData.getData('text/html')\r\n const text = e.clipboardData.getData('text/plain')\r\n const files = Array.from(e.clipboardData.files || [])\r\n const msExcelCheck = /<meta.*?Microsoft Excel\\s[\\d].*?>/\r\n\r\n if (html.search(msExcelCheck) === -1 && files.length > 0) {\r\n this.quill.uploader.upload(range, files)\r\n }\r\n else {\r\n const msWordCheck1\r\n = /<meta\\s*name=\"?generator\"?\\s*content=\"?microsoft\\s*word\\s*\\d+\"?\\/?>/i\r\n const msWordCheck2 = /xmlns:o=\"urn:schemas-microsoft-com/i\r\n const result = { html, text, files, rtf: null }\r\n if (html.search(msExcelCheck) !== -1) {\r\n result.html = renderStyles(html)\r\n }\r\n if (msWordCheck1.test(html) || msWordCheck2.test(html)) {\r\n // TODO: 当word文档包含heading时text/rtf读取为空,无法获取hex图片,待修复。可参考ckeditor5/issues/2493\r\n result.rtf = e.clipboardData.getData('text/rtf')\r\n }\r\n this.onPaste(range, result)\r\n }\r\n }\r\n\r\n onPaste(range, { html, text, files: clipboardFiles, rtf }) {\r\n const hexImages = this.extractImageDataFromRtf(rtf)\r\n const rootBgColor = getComputedStyle(this.quill.root)['backgroundColor']\r\n const formats = this.quill.getFormat(range.index)\r\n let pastedDelta = this.convert({ text, html }, formats)\r\n pastedDelta = replaceDeltaWhiteSpace(pastedDelta, rootBgColor)\r\n const deltaLength = pastedDelta.ops.length\r\n\r\n let loadingTipsContainer\r\n if (deltaLength > BIG_DELTA_LIMIT) {\r\n loadingTipsContainer = this.quill.addContainer('ql-loading-tips')\r\n loadingTipsContainer.innerHTML = LANG_CONF['pasting']\r\n }\r\n\r\n const linePos = { index: range.index, length: range.length, fix: 0 }\r\n const [line, offset] = this.quill.getLine(range.index)\r\n const isInsideTable = insideTable.call(this)\r\n\r\n const handlePasteContent = (content: any) => {\r\n let pastedContent = content\r\n // fix: 阻止粘贴代码块和引用导致表格断裂\r\n const tableBreaker = pastedContent.ops.find((op) => {\r\n return (\r\n op.attributes\r\n && (op.attributes['blockquote'] || op.attributes['code-block'])\r\n )\r\n })\r\n if (isInsideTable) {\r\n // fix: 阻止带有表格内容粘贴在表格里\r\n const table = line.domNode.closest('table.quill-better-table')\r\n const tableBlot = Quill.find(table)\r\n const tableIndex = this.quill.getIndex(tableBlot)\r\n const tableLength = tableBlot.length()\r\n const tableEndPos = tableIndex + tableLength\r\n const anchorNode = getSelection().anchorNode\r\n if (tableBreaker) {\r\n return\r\n }\r\n if (formats['table-col']) {\r\n // fix: 光标在表格前端的table-col处时,获取整个表格的index后以此为基准向前移动一位插入粘贴内容且不删除任何内容\r\n linePos.index = tableIndex - 1\r\n linePos.length = 0\r\n }\r\n else if (\r\n range.index === tableEndPos - 1\r\n && anchorNode instanceof HTMLDivElement\r\n && anchorNode.classList.contains('quill-better-table-wrapper')\r\n ) {\r\n const list = pastedContent.filter(\r\n op => op.attributes && op.attributes['list'],\r\n )\r\n if (list && list.length) {\r\n return\r\n }\r\n // fix: 光标在表格末端时,向后移动一位插入粘贴内容且不删除任何内容\r\n // TODO\r\n // 当表格最后一格有内容时,没法区分在表格最后一格最末尾和光标在表格后这两种情况,它们的 range 是一样\r\n // 这会导致在这两处粘贴表格内容都会将该内容粘贴到表格下一行中\r\n linePos.index = tableEndPos\r\n linePos.length = 0\r\n }\r\n else {\r\n if (!formats['table-cell-line']) {\r\n return\r\n }\r\n // fix: 解决表格内粘贴问题\r\n // 缺陷描述:将表格内的换行文本复制粘贴到别的单元格,会导致表格断开\r\n // 原因是:换行的文本delta对象有问题,delta对象前面多了一个纯换行和表格控制头(table-col)\r\n // 解决方法:将多余的delta项移除\r\n pastedContent = {\r\n ops: pastedContent.filter((op, index) => {\r\n const regexp = /^[\\n\\r]+$/\r\n const isString = op.insert && typeof op.insert === 'string'\r\n const isLine = isString && regexp.test(op.insert)\r\n const isCellLine\r\n = isLine && op.attributes && op.attributes['table-cell-line']\r\n const isList = isLine && op.attributes && op.attributes['list']\r\n const isPureLine = isLine && !isCellLine && !isList\r\n const isTableCol\r\n = isLine && op.attributes && op.attributes['table-col']\r\n const isLastCellLine = isCellLine && index === deltaLength - 1\r\n return !isPureLine && !isTableCol && !isLastCellLine\r\n }),\r\n }\r\n // fix: 解决从表格外粘贴多行文本导致表格断开的问题\r\n pastedContent = rebuildDelta(\r\n new Delta(pastedContent.ops),\r\n formats['table-cell-line'],\r\n )\r\n }\r\n }\r\n\r\n // fix: 粘贴内容末尾为List,且粘贴位置的block或table-cell-line无内容则删除该block或table-cell-line\r\n // TODO 这里的lastChild如果不存在,则可能报错\r\n const lastChild = pastedContent.ops[pastedContent.ops.length - 1]\r\n const hasList\r\n = lastChild && lastChild.attributes && lastChild.attributes['list']\r\n if (\r\n hasList\r\n && offset === 0\r\n && line\r\n && line.cache.length === 1\r\n && (line.statics.blotName === 'block'\r\n || line.statics.blotName === 'table-cell-line')\r\n && (!line.next || line.next.statics.blotName !== 'table-view')\r\n ) {\r\n linePos.index = this.quill.getIndex(line)\r\n linePos.length = line.length()\r\n linePos.fix = 1\r\n }\r\n\r\n const oldDelta = new Delta().retain(linePos.index).delete(linePos.length)\r\n const delta = oldDelta.concat(pastedContent)\r\n\r\n setTimeout(() => {\r\n this.quill.updateContents(delta, Quill.sources.USER)\r\n this.quill.setSelection(\r\n delta.length() - linePos.length - linePos.fix,\r\n Quill.sources.SILENT,\r\n )\r\n this.quill.scrollIntoView()\r\n if (loadingTipsContainer) {\r\n loadingTipsContainer.remove()\r\n }\r\n })\r\n }\r\n\r\n ;(async () => {\r\n try {\r\n const [files, placeholders, originalUrls, imageIndexs] = this.flipFilesArray(\r\n await this.extractFilesFromDelta(\r\n pastedDelta,\r\n clipboardFiles,\r\n hexImages,\r\n ),\r\n )\r\n\r\n if (files.length === 0) {\r\n handlePasteContent(pastedDelta)\r\n }\r\n else {\r\n if (this.quill.options.editorPaste && this.quill.options.editorPaste.observers.length !== 0) {\r\n // 设置editorPaste回调的情况\r\n this.quill.options.editorPaste.emit({\r\n files: files,\r\n callback: ({ code, message, data }) => {\r\n if (code === 0) {\r\n const { imageUrls } = data\r\n pastedDelta = replaceDeltaImage(\r\n pastedDelta,\r\n imageUrls,\r\n placeholders,\r\n )\r\n handlePasteContent(pastedDelta)\r\n }\r\n else {\r\n console.error('error message:', message)\r\n }\r\n },\r\n })\r\n }\r\n else {\r\n // 没有originalUrls 也没有文件粘贴\r\n if (files[0] !== undefined || originalUrls.length === 0) {\r\n // 没有设置editorPaste回调的情况下,File格式的占位图需要手动转换成url格式,插入到编辑器中\r\n const imageUrls = await this.files2urls(\r\n files,\r\n placeholders,\r\n originalUrls,\r\n pastedDelta,\r\n imageIndexs,\r\n )\r\n pastedDelta = replaceDeltaImage(\r\n pastedDelta,\r\n imageUrls,\r\n placeholders,\r\n )\r\n }\r\n handlePasteContent(pastedDelta)\r\n }\r\n }\r\n }\r\n catch (_e) {\r\n throw new Error('Paste failed.')\r\n }\r\n })()\r\n }\r\n\r\n files2urls(files, placeholders, originalUrls, pastedDelta, imageIndexs) {\r\n return Promise.all(\r\n files.map((imageFile, index) => {\r\n const netImgExp = /^((http|https)\\:)?\\/\\/([\\s\\S]+)$/\r\n if (\r\n !placeholders[index]\r\n && originalUrls[index]\r\n && netImgExp.test(originalUrls[index])\r\n ) {\r\n // 不是占位图的普通url图片直接返回url\r\n return new Promise((resolve) => {\r\n resolve(originalUrls[index])\r\n })\r\n }\r\n else if (this.quill.options.uploadOption.imageUploadToServer) {\r\n const range = this.getImgSelection(pastedDelta, imageIndexs[index])\r\n this.quill.uploader.upload(range, [imageFile])\r\n }\r\n else {\r\n // 占位图或者跨域图需要手动转换成url格式\r\n return imageFileToUrl(imageFile)\r\n }\r\n }),\r\n )\r\n }\r\n\r\n flipFilesArray(filesArr) {\r\n const files = []\r\n const placeholders = []\r\n const originalUrls = []\r\n const imageIndexs = []\r\n filesArr.forEach((item: any) => {\r\n if (item) {\r\n const [file, placeholder, originalUrl, imageIndex] = item\r\n files.push(file)\r\n placeholders.push(placeholder)\r\n originalUrls.push(originalUrl)\r\n if (imageIndex === 0 || imageIndex) {\r\n imageIndexs.push(imageIndex)\r\n }\r\n }\r\n })\r\n return [files, placeholders, originalUrls, imageIndexs]\r\n }\r\n\r\n // 将图片从hex转为base64\r\n convertHexToBase64(hexString) {\r\n return btoa(\r\n hexString\r\n .match(/\\w{2}/g)\r\n .map((char) => {\r\n return String.fromCharCode(parseInt(char, 16))\r\n })\r\n .join(''),\r\n )\r\n }\r\n\r\n // 匹配rtf中的图片,存储为{hex, type}对象数组\r\n extractImageDataFromRtf(rtfData) {\r\n if (!rtfData) {\r\n return []\r\n }\r\n\r\n const regexPictureHeader\r\n = /{\\\\pict[\\s\\S]+?\\\\bliptag-?\\d+(\\\\blipupi-?\\d+)?({\\\\\\*\\\\blipuid\\s?[\\da-fA-F]+)?[\\s}]*?/\r\n const regexPicture = new RegExp(\r\n '(?:(' + regexPictureHeader.source + '))([\\\\da-fA-F\\\\s]+)\\\\}',\r\n 'g',\r\n )\r\n const images = rtfData.match(regexPicture)\r\n const result = []\r\n\r\n if (images) {\r\n for (const image of images) {\r\n let imageType = ''\r\n\r\n if (image.includes('\\\\pngblip')) {\r\n imageType = 'image/png'\r\n }\r\n else if (image.includes('\\\\jpegblip')) {\r\n imageType = 'image/jpeg'\r\n }\r\n\r\n if (imageType) {\r\n result.push({\r\n hex: image\r\n .replace(regexPictureHeader, '')\r\n .replace(/[^\\da-fA-F]/g, ''),\r\n type: imageType,\r\n })\r\n }\r\n }\r\n }\r\n\r\n return result\r\n }\r\n\r\n extractFilesFromDelta(delta, clipboardFiles, hexImages?) {\r\n let index = -1\r\n return Promise.all(\r\n delta.map(async (op) => {\r\n index++\r\n const image = op.insert.image\r\n if (!image || image.hasExisted) {\r\n return\r\n }\r\n\r\n let file\r\n let isPlaceholderImage = false\r\n let imageIndex\r\n try {\r\n // hex 图片存在则为 file:/// 协议本地图片,使用 hex 图片转为 base64 读取\r\n const hexImage = hexImages.length && hexImages.shift()\r\n const newImage\r\n = hexImage\r\n && `data:${hexImage.type};base64,${this.convertHexToBase64(\r\n hexImage.hex,\r\n )}`\r\n imageIndex = index\r\n file = await imageUrlToFile(newImage || image.src || image)\r\n }\r\n catch (_err) {\r\n if (clipboardFiles.length !== 0) {\r\n // 跨域获取图片失败时从剪切板获取图片\r\n const clipboardFile = clipboardFiles[0]\r\n const imageType\r\n = clipboardFile.type?.indexOf('image') === -1\r\n ? 'image/png'\r\n : clipboardFile.type\r\n const blob = clipboardFile.slice(0, clipboardFile.size, imageType)\r\n file = new File([blob], `image-CORS-${new Date().getTime()}.png`, {\r\n type: imageType,\r\n })\r\n }\r\n else if (image.src.startsWith('http')) {\r\n // 什么都不做\r\n }\r\n else {\r\n // 剪切板中无图片,用失败占位图替换\r\n const errorImagePlaceholderJpg\r\n = LANG_CONF['img-error'] === 'Image Copy Error'\r\n ? ERROR_IMAGE_PLACEHOLDER_EN\r\n : ERROR_IMAGE_PLACEHOLDER_CN\r\n file = await imageUrlToFile(errorImagePlaceholderJpg, true)\r\n isPlaceholderImage = true\r\n }\r\n }\r\n\r\n return [file, isPlaceholderImage, image, imageIndex]\r\n }),\r\n )\r\n }\r\n\r\n getImgSelection(delta, imageIndex) {\r\n let length = 0\r\n delta.ops.every((op, index) => {\r\n if (index === imageIndex) {\r\n return false\r\n }\r\n if (typeof op.insert === 'string') {\r\n length += op.insert.length\r\n }\r\n return true\r\n })\r\n const range = {\r\n index: length,\r\n length: 0,\r\n }\r\n return range\r\n }\r\n}\r\n\r\nfunction rebuildDelta(delta, cellLine) {\r\n const { cell: cellId, colspan, row: rowId, rowspan } = cellLine\r\n const buildedDelta = delta.reduce((newDelta, op) => {\r\n if (op.insert && typeof op.insert === 'string') {\r\n const lines = splitWithBreak(op.insert)\r\n\r\n lines.forEach((text) => {\r\n if (text === '\\n') {\r\n // 对换行增加 table-cell-line 格式,以避免表格断开\r\n newDelta.insert('\\n', {\r\n ...op.attributes,\r\n 'table-cell-line': { row: rowId, cell: cellId, rowspan, colspan },\r\n })\r\n }\r\n else {\r\n text = text.endsWith('\\r') ? text.slice(0, -1) : text\r\n newDelta.insert(\r\n text,\r\n omit(op.attributes, ['table', 'table-cell-line']),\r\n )\r\n }\r\n })\r\n }\r\n else {\r\n newDelta.insert(op.insert, op.attributes)\r\n }\r\n\r\n return newDelta\r\n }, new Delta())\r\n\r\n return buildedDelta\r\n}\r\n\r\nfunction replaceStrWhiteSpace(str) {\r\n const isWhiteSpace = value => /^(\\u3000|\\u0020){1}$/.test(value) // 空白字符\r\n let textWithWhiteSpace = ''\r\n let beginHasChar = false\r\n for (const char of str) {\r\n if (isWhiteSpace(char) && !beginHasChar) {\r\n textWithWhiteSpace += '\\u00a0'\r\n }\r\n else {\r\n textWithWhiteSpace += char\r\n beginHasChar = true\r\n }\r\n }\r\n return textWithWhiteSpace\r\n}\r\n\r\nfunction replaceDeltaWhiteSpace(delta, rootBgColor?) {\r\n return delta.reduce((newDelta, op) => {\r\n // fix: 当粘贴文字颜色和编辑器背景色一致且自身无背景色的情况下移除文字颜色样式,避免误导用户粘贴无效\r\n if (\r\n rootBgColor\r\n && op.attributes\r\n && op.attributes.color\r\n && !op.attributes.background\r\n ) {\r\n const originColor = op.attributes.color\r\n const fontColor\r\n = originColor.indexOf('#') === 0 ? hexToRgbA(originColor) : originColor\r\n if (\r\n fontColor === rootBgColor\r\n || (fontColor === 'rgba(255,255,255,1)'\r\n && rootBgColor === 'rgba(0, 0, 0, 0)')\r\n ) {\r\n delete op.attributes.color\r\n }\r\n }\r\n if (op.insert && typeof op.insert === 'string') {\r\n const lines = splitWithBreak(op.insert)\r\n let insertWithWhiteSpace = ''\r\n lines.forEach((text) => {\r\n insertWithWhiteSpace += replaceStrWhiteSpace(text)\r\n })\r\n newDelta.insert(insertWithWhiteSpace, op.attributes)\r\n }\r\n else {\r\n newDelta.insert(op.insert, op.attributes)\r\n }\r\n return newDelta\r\n }, new Delta())\r\n}\r\n\r\nfunction renderStyles(html) {\r\n let htmlString = html\r\n // Trim unnecessary parts.\r\n htmlString = htmlString.substring(\r\n htmlString.indexOf('<html '),\r\n htmlString.length,\r\n )\r\n htmlString = htmlString.substring(\r\n 0,\r\n htmlString.lastIndexOf('</html>') + '</html>'.length,\r\n )\r\n\r\n // Add temporary iframe.\r\n const iframe = document.createElement('iframe')\r\n iframe.style.display = 'none'\r\n document.body.appendChild(iframe)\r\n\r\n const iframeDoc = iframe.contentDocument || iframe.contentWindow.document\r\n iframeDoc.open()\r\n iframeDoc.write(htmlString)\r\n iframeDoc.close()\r\n\r\n let collection\r\n let pointer\r\n const rules\r\n = iframeDoc.styleSheets[iframeDoc.styleSheets.length - 1]['cssRules']\r\n\r\n // Convert internal styles to inline style of respective node.\r\n for (let idx = 0; idx < rules.length; idx++) {\r\n if ((rules[idx] as CSSStyleRule).selectorText === '') {\r\n continue\r\n }\r\n collection = iframeDoc.body.querySelectorAll(\r\n (rules[idx] as CSSStyleRule).selectorText,\r\n )\r\n\r\n for (pointer = 0; pointer < collection.length; pointer++) {\r\n collection[pointer].style.cssText += (\r\n rules[idx] as CSSStyleRule\r\n ).style.cssText\r\n }\r\n }\r\n\r\n const convertedString = iframeDoc.firstChild['outerHTML']\r\n // Remove temporary iframe.\r\n iframe.parentNode.removeChild(iframe)\r\n\r\n return convertedString\r\n}\r\n\r\nexport default CustomClipboard\r\n"],"names":[],"mappings":";;;;AAiBA,MAAM,YAAY,MAAM,QAAQ,mBAAmB;AACnD,MAAM,QAAQ,MAAM,QAAQ,OAAO;AAEnC,MAAM,wBAAwB,UAAU;AAAA,EAMtC,gBAAgB,WAAW,aAAa;AACtC,UAAM,kBAAkB,CAAA;AACxB,UAAM,eAAe,CAAA;AAChB,SAAA,SAAS,QAAQ,CAAC,SAAS;AACxB,YAAA,CAAC,UAAU,OAAO,IAAI;AAC5B,cAAQ,UAAU;AAAA,QAChB,KAAK,KAAK;AACR,uBAAa,KAAK,OAAO;AACzB;AAAA,QACF,KAAK,KAAK;AACR,0BAAgB,KAAK,OAAO;AAC5B;AAAA,QACF,SAAS;AAEP,gBAAM,SAAS;AACf,gBAAM,WAAW,OAAO,KAAK,QAAQ,IACjC,MAAM,KAAK,UAAU,qBAAqB,QAAQ,CAAC,IACnD,MAAM,KAAK,UAAU,iBAAiB,QAAQ,CAAC;AAC1C,mBAAA,QAAQ,CAAC,SAAS;AACrB,gBAAA,YAAY,IAAI,IAAI,GAAG;AACnB,oBAAA,UAAU,YAAY,IAAI,IAAI;AACpC,sBAAQ,KAAK,OAAO;AAAA,YAAA,OAEjB;AACH,0BAAY,IAAI,MAAM,CAAC,OAAO,CAAC;AAAA,YACjC;AAAA,UAAA,CACD;AACD;AAAA,QACF;AAAA,MACF;AAAA,IAAA,CACD;AACM,WAAA,CAAC,iBAAiB,YAAY;AAAA,EACvC;AAAA,EAEA,cAAc,GAAG,QAAQ,OAAO;AAC9B,QAAI,EAAE,kBAAkB;AACtB;AAAA,IACF;AACA,MAAE,eAAe;AACjB,UAAM,CAAC,KAAK,IAAI,KAAK,MAAM,UAAU;AACjC,QAAA,kBAAkB,KAAK,GAAG;AAC5B;AAAA,IACF;AACA,UAAM,EAAE,MAAM,SAAS,KAAK,OAAO,OAAO,KAAK;AAG3C,QAAA,CAAC,EAAE,eAAe;AACpB,QAAE,gBAAgB;AAAA,QAChB,OAAO;AAAA,QACP,SAAS,CAAC,OAAO,UAAU;AACzB,iBAAO,OAAO,eAAe,EAAE,QAAQ,QAAQ,KAAK;AAAA,QACtD;AAAA,MAAA;AAAA,IAEJ;AAGA,QAAI,YAAY;AACZ,QAAA,KAAK,WAAW,OAAO,GAAG;AAChB,kBAAA,KAAK,QAAQ,WAAW,GAAG;AAAA,IACzC;AAEE,MAAA,cAAc,QAAQ,aAAa,IAAI;AACvC,MAAA,cAAc,QAAQ,cAAc,SAAS;AAC/C,QAAI,OAAO;AACT,WAAK,MAAM,WAAW,OAAO,MAAM,QAAQ,IAAI;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,eAAe,GAAG;AAChB,QAAI,EAAE,oBAAoB,CAAC,KAAK,MAAM,aAAa;AACjD;AAAA,IACF;AACA,MAAE,eAAe;AACjB,UAAM,QAAQ,KAAK,MAAM,aAAa,IAAI;AACtC,QAAA,kBAAkB,KAAK,GAAG;AAC5B;AAAA,IACF;AAGI,QAAA,CAAC,EAAE,eAAe;AACpB,QAAE,gBAAgB;AAAA,QAChB,OAAO;AAAA,QACP,SAAS,MAAM;AACb,iBAAO,OAAO,eAAe,EAAE,QAAQ,MAAM;AAAA,QAC/C;AAAA,MAAA;AAAA,IAEJ;AAEA,UAAM,OAAO,EAAE,cAAc,QAAQ,WAAW;AAChD,UAAM,OAAO,EAAE,cAAc,QAAQ,YAAY;AACjD,UAAM,QAAQ,MAAM,KAAK,EAAE,cAAc,SAAS,CAAA,CAAE;AACpD,UAAM,eAAe;AAErB,QAAI,KAAK,OAAO,YAAY,MAAM,MAAM,MAAM,SAAS,GAAG;AACxD,WAAK,MAAM,SAAS,OAAO,OAAO,KAAK;AAAA,IAAA,OAEpC;AACH,YAAM,eACF;AACJ,YAAM,eAAe;AACrB,YAAM,SAAS,EAAE,MAAM,MAAM,OAAO,KAAK;AACzC,UAAI,KAAK,OAAO,YAAY,MAAM,IAAI;AAC7B,eAAA,OAAO,aAAa,IAAI;AAAA,MACjC;AACA,UAAI,aAAa,KAAK,IAAI,KAAK,aAAa,KAAK,IAAI,GAAG;AAEtD,eAAO,MAAM,EAAE,cAAc,QAAQ,UAAU;AAAA,MACjD;AACK,WAAA,QAAQ,OAAO,MAAM;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,QAAQ,OAAO,EAAE,MAAM,MAAM,OAAO,gBAAgB,OAAO;AACnD,UAAA,YAAY,KAAK,wBAAwB,GAAG;AAClD,UAAM,cAAc,iBAAiB,KAAK,MAAM,IAAI,EAAE,iBAAiB;AACvE,UAAM,UAAU,KAAK,MAAM,UAAU,MAAM,KAAK;AAChD,QAAI,cAAc,KAAK,QAAQ,EAAE,MAAM,KAAA,GAAQ,OAAO;AACxC,kBAAA,uBAAuB,aAAa,WAAW;AACvD,UAAA,cAAc,YAAY,IAAI;AAEhC,QAAA;AACJ,QAAI,cAAc,iBAAiB;AACV,6BAAA,KAAK,MAAM,aAAa,iBAAiB;AAC3C,2BAAA,YAAY,UAAU,SAAS;AAAA,IACtD;AAEM,UAAA,UAAU,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,KAAK;AAC3D,UAAA,CAAC,MAAM,MAAM,IAAI,KAAK,MAAM,QAAQ,MAAM,KAAK;AAC/C,UAAA,gBAAgB,YAAY,KAAK,IAAI;AAErC,UAAA,qBAAqB,CAAC,YAAiB;AAC3C,UAAI,gBAAgB;AAEpB,YAAM,eAAe,cAAc,IAAI,KAAK,CAAC,OAAO;AAEhD,eAAA,GAAG,eACC,GAAG,WAAW,YAAY,KAAK,GAAG,WAAW,YAAY;AAAA,MAAA,CAEhE;AACD,UAAI,eAAe;AAEjB,cAAM,QAAQ,KAAK,QAAQ,QAAQ,0BAA0B;AACvD,cAAA,YAAY,MAAM,KAAK,KAAK;AAClC,cAAM,aAAa,KAAK,MAAM,SAAS,SAAS;AAC1C,cAAA,cAAc,UAAU;AAC9B,cAAM,cAAc,aAAa;AAC3B,cAAA,aAAa,aAAe,EAAA;AAClC,YAAI,cAAc;AAChB;AAAA,QACF;AACI,YAAA,QAAQ,WAAW,GAAG;AAExB,kBAAQ,QAAQ,aAAa;AAC7B,kBAAQ,SAAS;AAAA,QACnB,WAEE,MAAM,UAAU,cAAc,KAC3B,sBAAsB,kBACtB,WAAW,UAAU,SAAS,4BAA4B,GAC7D;AACA,gBAAM,OAAO,cAAc;AAAA,YACzB,CAAM,OAAA,GAAG,cAAc,GAAG,WAAW,MAAM;AAAA,UAAA;AAEzC,cAAA,QAAQ,KAAK,QAAQ;AACvB;AAAA,UACF;AAKA,kBAAQ,QAAQ;AAChB,kBAAQ,SAAS;AAAA,QAAA,OAEd;AACC,cAAA,CAAC,QAAQ,iBAAiB,GAAG;AAC/B;AAAA,UACF;AAKgB,0BAAA;AAAA,YACd,KAAK,cAAc,OAAO,CAAC,IAAI,UAAU;AACvC,oBAAM,SAAS;AACf,oBAAM,WAAW,GAAG,UAAU,OAAO,GAAG,WAAW;AACnD,oBAAM,SAAS,YAAY,OAAO,KAAK,GAAG,MAAM;AAChD,oBAAM,aACF,UAAU,GAAG,cAAc,GAAG,WAAW,iBAAiB;AAC9D,oBAAM,SAAS,UAAU,GAAG,cAAc,GAAG,WAAW,MAAM;AAC9D,oBAAM,aAAa,UAAU,CAAC,cAAc,CAAC;AAC7C,oBAAM,aACF,UAAU,GAAG,cAAc,GAAG,WAAW,WAAW;AAClD,oBAAA,iBAAiB,cAAc,UAAU,cAAc;AAC7D,qBAAO,CAAC,cAAc,CAAC,cAAc,CAAC;AAAA,YAAA,CACvC;AAAA,UAAA;AAGa,0BAAA;AAAA,YACd,IAAI,MAAM,cAAc,GAAG;AAAA,YAC3B,QAAQ,iBAAiB;AAAA,UAAA;AAAA,QAE7B;AAAA,MACF;AAIA,YAAM,YAAY,cAAc,IAAI,cAAc,IAAI,SAAS,CAAC;AAChE,YAAM,UACF,aAAa,UAAU,cAAc,UAAU,WAAW,MAAM;AAElE,UAAA,WACG,WAAW,KACX,QACA,KAAK,MAAM,WAAW,MACrB,KAAK,QAAQ,aAAa,WAC3B,KAAK,QAAQ,aAAa,uBACzB,CAAC,KAAK,QAAQ,KAAK,KAAK,QAAQ,aAAa,eACjD;AACA,gBAAQ,QAAQ,KAAK,MAAM,SAAS,IAAI;AAChC,gBAAA,SAAS,KAAK;AACtB,gBAAQ,MAAM;AAAA,MAChB;AAEM,YAAA,WAAW,IAAI,MAAQ,EAAA,OAAO,QAAQ,KAAK,EAAE,OAAO,QAAQ,MAAM;AAClE,YAAA,QAAQ,SAAS,OAAO,aAAa;AAE3C,iBAAW,MAAM;AACf,aAAK,MAAM,eAAe,OAAO,MAAM,QAAQ,IAAI;AACnD,aAAK,MAAM;AAAA,UACT,MAAM,OAAW,IAAA,QAAQ,SAAS,QAAQ;AAAA,UAC1C,MAAM,QAAQ;AAAA,QAAA;AAEhB,aAAK,MAAM;AACX,YAAI,sBAAsB;AACxB,+BAAqB,OAAO;AAAA,QAC9B;AAAA,MAAA,CACD;AAAA,IAAA;AAGF,KAAC,YAAY;AACR,UAAA;AACF,cAAM,CAAC,OAAO,cAAc,cAAc,WAAW,IAAI,KAAK;AAAA,UAC5D,MAAM,KAAK;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QAAA;AAGE,YAAA,MAAM,WAAW,GAAG;AACtB,6BAAmB,WAAW;AAAA,QAAA,OAE3B;AACC,cAAA,KAAK,MAAM,QAAQ,eAAe,KAAK,MAAM,QAAQ,YAAY,UAAU,WAAW,GAAG;AAEtF,iBAAA,MAAM,QAAQ,YAAY,KAAK;AAAA,cAClC;AAAA,cACA,UAAU,CAAC,EAAE,MAAM,SAAS,WAAW;AACrC,oBAAI,SAAS,GAAG;AACR,wBAAA,EAAE,UAAc,IAAA;AACR,gCAAA;AAAA,oBACZ;AAAA,oBACA;AAAA,oBACA;AAAA,kBAAA;AAEF,qCAAmB,WAAW;AAAA,gBAAA,OAE3B;AACK,0BAAA,MAAM,kBAAkB,OAAO;AAAA,gBACzC;AAAA,cACF;AAAA,YAAA,CACD;AAAA,UAAA,OAEE;AAEH,gBAAI,MAAM,CAAC,MAAM,UAAa,aAAa,WAAW,GAAG;AAEjD,oBAAA,YAAY,MAAM,KAAK;AAAA,gBAC3B;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAEY,4BAAA;AAAA,gBACZ;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAEJ;AACA,+BAAmB,WAAW;AAAA,UAChC;AAAA,QACF;AAAA,eAEK,IAAI;AACH,cAAA,IAAI,MAAM,eAAe;AAAA,MACjC;AAAA,IAAA;EAEJ;AAAA,EAEA,WAAW,OAAO,cAAc,cAAc,aAAa,aAAa;AACtE,WAAO,QAAQ;AAAA,MACb,MAAM,IAAI,CAAC,WAAW,UAAU;AAC9B,cAAM,YAAY;AAClB,YACE,CAAC,aAAa,KAAK,KAChB,aAAa,KAAK,KAClB,UAAU,KAAK,aAAa,KAAK,CAAC,GACrC;AAEO,iBAAA,IAAI,QAAQ,CAAC,YAAY;AACtB,oBAAA,aAAa,KAAK,CAAC;AAAA,UAAA,CAC5B;AAAA,QAEM,WAAA,KAAK,MAAM,QAAQ,aAAa,qBAAqB;AAC5D,gBAAM,QAAQ,KAAK,gBAAgB,aAAa,YAAY,KAAK,CAAC;AAClE,eAAK,MAAM,SAAS,OAAO,OAAO,CAAC,SAAS,CAAC;AAAA,QAAA,OAE1C;AAEH,iBAAO,eAAe,SAAS;AAAA,QACjC;AAAA,MAAA,CACD;AAAA,IAAA;AAAA,EAEL;AAAA,EAEA,eAAe,UAAU;AACvB,UAAM,QAAQ,CAAA;AACd,UAAM,eAAe,CAAA;AACrB,UAAM,eAAe,CAAA;AACrB,UAAM,cAAc,CAAA;AACX,aAAA,QAAQ,CAAC,SAAc;AAC9B,UAAI,MAAM;AACR,cAAM,CAAC,MAAM,aAAa,aAAa,UAAU,IAAI;AACrD,cAAM,KAAK,IAAI;AACf,qBAAa,KAAK,WAAW;AAC7B,qBAAa,KAAK,WAAW;AACzB,YAAA,eAAe,KAAK,YAAY;AAClC,sBAAY,KAAK,UAAU;AAAA,QAC7B;AAAA,MACF;AAAA,IAAA,CACD;AACD,WAAO,CAAC,OAAO,cAAc,cAAc,WAAW;AAAA,EACxD;AAAA;AAAA,EAGA,mBAAmB,WAAW;AACrB,WAAA;AAAA,MACL,UACG,MAAM,QAAQ,EACd,IAAI,CAAC,SAAS;AACb,eAAO,OAAO,aAAa,SAAS,MAAM,EAAE,CAAC;AAAA,MAAA,CAC9C,EACA,KAAK,EAAE;AAAA,IAAA;AAAA,EAEd;AAAA;AAAA,EAGA,wBAAwB,SAAS;AAC/B,QAAI,CAAC,SAAS;AACZ,aAAO;IACT;AAEA,UAAM,qBACF;AACJ,UAAM,eAAe,IAAI;AAAA,MACvB,SAAS,mBAAmB,SAAS;AAAA,MACrC;AAAA,IAAA;AAEI,UAAA,SAAS,QAAQ,MAAM,YAAY;AACzC,UAAM,SAAS,CAAA;AAEf,QAAI,QAAQ;AACV,iBAAW,SAAS,QAAQ;AAC1B,YAAI,YAAY;AAEZ,YAAA,MAAM,SAAS,WAAW,GAAG;AACnB,sBAAA;AAAA,QAEL,WAAA,MAAM,SAAS,YAAY,GAAG;AACzB,sBAAA;AAAA,QACd;AAEA,YAAI,WAAW;AACb,iBAAO,KAAK;AAAA,YACV,KAAK,MACF,QAAQ,oBAAoB,EAAE,EAC9B,QAAQ,gBAAgB,EAAE;AAAA,YAC7B,MAAM;AAAA,UAAA,CACP;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEO,WAAA;AAAA,EACT;AAAA,EAEA,sBAAsB,OAAO,gBAAgB,WAAY;AACvD,QAAI,QAAQ;AACZ,WAAO,QAAQ;AAAA,MACb,MAAM,IAAI,OAAO,OAAO;;AACtB;AACM,cAAA,QAAQ,GAAG,OAAO;AACpB,YAAA,CAAC,SAAS,MAAM,YAAY;AAC9B;AAAA,QACF;AAEI,YAAA;AACJ,YAAI,qBAAqB;AACrB,YAAA;AACA,YAAA;AAEF,gBAAM,WAAW,UAAU,UAAU,UAAU,MAAM;AACrD,gBAAM,WACF,YACC,QAAQ,SAAS,IAAI,WAAW,KAAK;AAAA,YACtC,SAAS;AAAA,UACV,CAAA;AACU,uBAAA;AACb,iBAAO,MAAM,eAAe,YAAY,MAAM,OAAO,KAAK;AAAA,iBAErD,MAAM;AACP,cAAA,eAAe,WAAW,GAAG;AAEzB,kBAAA,gBAAgB,eAAe,CAAC;AAChC,kBAAA,cACF,mBAAc,SAAd,mBAAoB,QAAQ,cAAa,KACvC,cACA,cAAc;AACpB,kBAAM,OAAO,cAAc,MAAM,GAAG,cAAc,MAAM,SAAS;AAC1D,mBAAA,IAAI,KAAK,CAAC,IAAI,GAAG,eAAc,oBAAI,KAAK,GAAE,QAAS,CAAA,QAAQ;AAAA,cAChE,MAAM;AAAA,YAAA,CACP;AAAA,UAEM,WAAA,MAAM,IAAI,WAAW,MAAM,GAAG;AAAA,UAAA,OAGlC;AAEH,kBAAM,2BACF,UAAU,WAAW,MAAM,qBACzB,6BACA;AACC,mBAAA,MAAM,eAAe,0BAA0B,IAAI;AACrC,iCAAA;AAAA,UACvB;AAAA,QACF;AAEA,eAAO,CAAC,MAAM,oBAAoB,OAAO,UAAU;AAAA,MAAA,CACpD;AAAA,IAAA;AAAA,EAEL;AAAA,EAEA,gBAAgB,OAAO,YAAY;AACjC,QAAI,SAAS;AACb,UAAM,IAAI,MAAM,CAAC,IAAI,UAAU;AAC7B,UAAI,UAAU,YAAY;AACjB,eAAA;AAAA,MACT;AACI,UAAA,OAAO,GAAG,WAAW,UAAU;AACjC,kBAAU,GAAG,OAAO;AAAA,MACtB;AACO,aAAA;AAAA,IAAA,CACR;AACD,UAAM,QAAQ;AAAA,MACZ,OAAO;AAAA,MACP,QAAQ;AAAA,IAAA;AAEH,WAAA;AAAA,EACT;AACF;AAEA,SAAS,aAAa,OAAO,UAAU;AACrC,QAAM,EAAE,MAAM,QAAQ,SAAS,KAAK,OAAO,QAAY,IAAA;AACvD,QAAM,eAAe,MAAM,OAAO,CAAC,UAAU,OAAO;AAClD,QAAI,GAAG,UAAU,OAAO,GAAG,WAAW,UAAU;AACxC,YAAA,QAAQ,eAAe,GAAG,MAAM;AAEhC,YAAA,QAAQ,CAAC,SAAS;AACtB,YAAI,SAAS,MAAM;AAEjB,mBAAS,OAAO,MAAM;AAAA,YACpB,GAAG,GAAG;AAAA,YACN,mBAAmB,EAAE,KAAK,OAAO,MAAM,QAAQ,SAAS,QAAQ;AAAA,UAAA,CACjE;AAAA,QAAA,OAEE;AACI,iBAAA,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;AACxC,mBAAA;AAAA,YACP;AAAA,YACA,KAAK,GAAG,YAAY,CAAC,SAAS,iBAAiB,CAAC;AAAA,UAAA;AAAA,QAEpD;AAAA,MAAA,CACD;AAAA,IAAA,OAEE;AACH,eAAS,OAAO,GAAG,QAAQ,GAAG,UAAU;AAAA,IAC1C;AAEO,WAAA;AAAA,EAAA,GACN,IAAI,MAAA,CAAO;AAEP,SAAA;AACT;AAEA,SAAS,qBAAqB,KAAK;AACjC,QAAM,eAAe,CAAA,UAAS,uBAAuB,KAAK,KAAK;AAC/D,MAAI,qBAAqB;AACzB,MAAI,eAAe;AACnB,aAAW,QAAQ,KAAK;AACtB,QAAI,aAAa,IAAI,KAAK,CAAC,cAAc;AACjB,4BAAA;AAAA,IAAA,OAEnB;AACmB,4BAAA;AACP,qBAAA;AAAA,IACjB;AAAA,EACF;AACO,SAAA;AACT;AAEA,SAAS,uBAAuB,OAAO,aAAc;AACnD,SAAO,MAAM,OAAO,CAAC,UAAU,OAAO;AAGlC,QAAA,eACG,GAAG,cACH,GAAG,WAAW,SACd,CAAC,GAAG,WAAW,YAClB;AACM,YAAA,cAAc,GAAG,WAAW;AAC5B,YAAA,YACF,YAAY,QAAQ,GAAG,MAAM,IAAI,UAAU,WAAW,IAAI;AAC9D,UACE,cAAc,eACV,cAAc,yBACf,gBAAgB,oBACnB;AACA,eAAO,GAAG,WAAW;AAAA,MACvB;AAAA,IACF;AACA,QAAI,GAAG,UAAU,OAAO,GAAG,WAAW,UAAU;AACxC,YAAA,QAAQ,eAAe,GAAG,MAAM;AACtC,UAAI,uBAAuB;AACrB,YAAA,QAAQ,CAAC,SAAS;AACtB,gCAAwB,qBAAqB,IAAI;AAAA,MAAA,CAClD;AACQ,eAAA,OAAO,sBAAsB,GAAG,UAAU;AAAA,IAAA,OAEhD;AACH,eAAS,OAAO,GAAG,QAAQ,GAAG,UAAU;AAAA,IAC1C;AACO,WAAA;AAAA,EAAA,GACN,IAAI,MAAA,CAAO;AAChB;AAEA,SAAS,aAAa,MAAM;AAC1B,MAAI,aAAa;AAEjB,eAAa,WAAW;AAAA,IACtB,WAAW,QAAQ,QAAQ;AAAA,IAC3B,WAAW;AAAA,EAAA;AAEb,eAAa,WAAW;AAAA,IACtB;AAAA,IACA,WAAW,YAAY,SAAS,IAAI,UAAU;AAAA,EAAA;AAI1C,QAAA,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM,UAAU;AACd,WAAA,KAAK,YAAY,MAAM;AAEhC,QAAM,YAAY,OAAO,mBAAmB,OAAO,cAAc;AACjE,YAAU,KAAK;AACf,YAAU,MAAM,UAAU;AAC1B,YAAU,MAAM;AAEZ,MAAA;AACA,MAAA;AACE,QAAA,QACF,UAAU,YAAY,UAAU,YAAY,SAAS,CAAC,EAAE,UAAU;AAGtE,WAAS,MAAM,GAAG,MAAM,MAAM,QAAQ,OAAO;AAC3C,QAAK,MAAM,GAAG,EAAmB,iBAAiB,IAAI;AACpD;AAAA,IACF;AACA,iBAAa,UAAU,KAAK;AAAA,MACzB,MAAM,GAAG,EAAmB;AAAA,IAAA;AAG/B,SAAK,UAAU,GAAG,UAAU,WAAW,QAAQ,WAAW;AACxD,iBAAW,OAAO,EAAE,MAAM,WACxB,MAAM,GAAG,EACT,MAAM;AAAA,IACV;AAAA,EACF;AAEM,QAAA,kBAAkB,UAAU,WAAW,WAAW;AAEjD,SAAA,WAAW,YAAY,MAAM;AAE7B,SAAA;AACT;"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import Quill from "quill";
|
|
2
|
+
import CustomImage, { ImageContainerBlot as CustomImageContainer } from "./image.es.js";
|
|
3
|
+
import DefaultOptions from "./Options.es.js";
|
|
4
|
+
import { CustomImageSpec } from "./specs/CustomImageSpec.es.js";
|
|
5
|
+
import { merge } from "lodash-es";
|
|
6
|
+
const dontMerge = (_destination, source) => source;
|
|
7
|
+
class BlotFormatter {
|
|
8
|
+
constructor(quill, options = {}) {
|
|
9
|
+
this.onClick = () => {
|
|
10
|
+
this.hide();
|
|
11
|
+
};
|
|
12
|
+
this.hideImageOverlay = (event) => {
|
|
13
|
+
var _a;
|
|
14
|
+
const target = event.target;
|
|
15
|
+
const isBlotFormatter = (_a = target == null ? void 0 : target.classList) == null ? void 0 : _a.contains("blot-formatter__overlay");
|
|
16
|
+
if (!isBlotFormatter) {
|
|
17
|
+
this.hide();
|
|
18
|
+
}
|
|
19
|
+
document.body.removeEventListener("click", this.hideImageOverlay);
|
|
20
|
+
};
|
|
21
|
+
this.quill = quill;
|
|
22
|
+
this.options = merge(DefaultOptions, options, { arrayMerge: dontMerge });
|
|
23
|
+
this.currentSpec = null;
|
|
24
|
+
this.actions = [];
|
|
25
|
+
this.overlay = document.createElement("div");
|
|
26
|
+
this.overlay.classList.add(this.options.overlay.className);
|
|
27
|
+
if (this.options.overlay.style) {
|
|
28
|
+
Object.assign(this.overlay.style, this.options.overlay.style);
|
|
29
|
+
}
|
|
30
|
+
document.execCommand("enableObjectResizing", false, "false");
|
|
31
|
+
this.quill.root.parentNode.style.position = this.quill.root.parentNode.style.position || "relative";
|
|
32
|
+
this.quill.root.addEventListener("click", this.onClick);
|
|
33
|
+
this.specs = this.options.specs.map((SpecClass) => new SpecClass(this));
|
|
34
|
+
this.specs.forEach((spec) => spec.init());
|
|
35
|
+
}
|
|
36
|
+
static register() {
|
|
37
|
+
Quill.register("formats/image", CustomImage, true);
|
|
38
|
+
Quill.register("formats/image-container", CustomImageContainer, true);
|
|
39
|
+
Quill.register("modules/image-spec", CustomImageSpec, true);
|
|
40
|
+
}
|
|
41
|
+
show(spec) {
|
|
42
|
+
this.currentSpec = spec;
|
|
43
|
+
this.currentSpec.setSelection();
|
|
44
|
+
this.setUserSelect("none");
|
|
45
|
+
this.quill.root.parentNode.appendChild(this.overlay);
|
|
46
|
+
this.repositionOverlay();
|
|
47
|
+
this.createActions(spec);
|
|
48
|
+
const imageDom = spec.getTargetElement();
|
|
49
|
+
const win = window;
|
|
50
|
+
const MutationObserver = win.MutationObserver || win.WebKitMutationObserver || win.MozMutationObserver;
|
|
51
|
+
const element = imageDom.parentNode;
|
|
52
|
+
this.observer = new MutationObserver((mutationList) => {
|
|
53
|
+
for (const mutation of mutationList) {
|
|
54
|
+
const target = mutation.target;
|
|
55
|
+
const image = target.querySelector("img");
|
|
56
|
+
if (image) {
|
|
57
|
+
this.repositionOverlay();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
this.observer.observe(element, {
|
|
62
|
+
attributes: true,
|
|
63
|
+
attributeFilter: ["class"],
|
|
64
|
+
attributeOldValue: true,
|
|
65
|
+
subtree: true
|
|
66
|
+
});
|
|
67
|
+
document.body.addEventListener("click", this.hideImageOverlay, true);
|
|
68
|
+
}
|
|
69
|
+
hide() {
|
|
70
|
+
if (!this.currentSpec) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const imgDom = this.currentSpec.getTargetElement();
|
|
74
|
+
if (imgDom) {
|
|
75
|
+
imgDom.classList.remove("current-select-img");
|
|
76
|
+
}
|
|
77
|
+
this.currentSpec.onHide();
|
|
78
|
+
this.currentSpec = null;
|
|
79
|
+
this.quill.root.parentNode.removeChild(this.overlay);
|
|
80
|
+
this.overlay.style.setProperty("display", "none");
|
|
81
|
+
this.setUserSelect("");
|
|
82
|
+
this.destroyActions();
|
|
83
|
+
}
|
|
84
|
+
update() {
|
|
85
|
+
this.repositionOverlay();
|
|
86
|
+
this.actions.forEach((action) => action.onUpdate());
|
|
87
|
+
}
|
|
88
|
+
createActions(spec) {
|
|
89
|
+
this.actions = spec.getActions().map((ActionClass) => {
|
|
90
|
+
const action = new ActionClass(this);
|
|
91
|
+
action.onCreate();
|
|
92
|
+
return action;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
destroyActions() {
|
|
96
|
+
this.actions.forEach((action) => action.onDestroy());
|
|
97
|
+
this.actions = [];
|
|
98
|
+
}
|
|
99
|
+
repositionOverlay() {
|
|
100
|
+
if (!this.currentSpec) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const overlayTarget = this.currentSpec.getOverlayElement();
|
|
104
|
+
if (!overlayTarget) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const parent = this.quill.root.parentNode;
|
|
108
|
+
const specRect = overlayTarget.getBoundingClientRect();
|
|
109
|
+
const parentRect = parent.getBoundingClientRect();
|
|
110
|
+
Object.assign(this.overlay.style, {
|
|
111
|
+
display: "block",
|
|
112
|
+
left: `${specRect.left - parentRect.left - 1 + parent.scrollLeft}px`,
|
|
113
|
+
top: `${specRect.top - parentRect.top + parent.scrollTop}px`,
|
|
114
|
+
width: `${specRect.width}px`,
|
|
115
|
+
height: `${specRect.height}px`
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
setUserSelect(value) {
|
|
119
|
+
const props = [
|
|
120
|
+
"userSelect",
|
|
121
|
+
"mozUserSelect",
|
|
122
|
+
"webkitUserSelect",
|
|
123
|
+
"msUserSelect"
|
|
124
|
+
];
|
|
125
|
+
props.forEach((prop) => {
|
|
126
|
+
this.quill.root.style.setProperty(prop, value);
|
|
127
|
+
if (document.documentElement) {
|
|
128
|
+
document.documentElement.style.setProperty(prop, value);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export {
|
|
134
|
+
BlotFormatter as default
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=BlotFormatter.es.js.map
|