@qxs-bns/components 0.0.91 → 0.0.92
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/es/base/define.mjs +1 -1
- package/es/base/define.mjs.map +1 -1
- package/es/base/uid.mjs +1 -1
- package/es/base/uid.mjs.map +1 -1
- package/es/data-chart.mjs +15 -14
- package/es/data-chart.mjs.map +1 -1
- package/es/editor/blocksuite-editor.mjs +62 -51
- package/es/editor/blocksuite-editor.mjs.map +1 -1
- package/es/editor/content-format.mjs +8 -1
- package/es/editor/content-format.mjs.map +1 -1
- package/es/editor/index.mjs +1 -1
- package/es/editor/index.mjs.map +1 -1
- package/es/editor/toolbar.mjs +1 -1
- package/es/editor/toolbar.mjs.map +1 -1
- package/es/entry-data-chart.mjs +1 -1
- package/es/entry-editor.mjs +1 -1
- package/es/entry-file-upload.mjs +1 -1
- package/es/entry-fixed-action-bar.mjs +1 -1
- package/es/entry-icon.mjs +1 -1
- package/es/entry-image-upload.mjs +1 -1
- package/es/entry-photo-crop-tool.mjs +1 -1
- package/es/entry-subject.mjs +1 -1
- package/es/file-upload.mjs +25 -18
- package/es/file-upload.mjs.map +1 -1
- package/es/fixed-action-bar.mjs +5 -5
- package/es/fixed-action-bar.mjs.map +1 -1
- package/es/icon.mjs +7 -7
- package/es/icon.mjs.map +1 -1
- package/es/image-upload.mjs +26 -26
- package/es/image-upload.mjs.map +1 -1
- package/es/index.mjs +1 -1
- package/es/node_modules/.pnpm/marked@17.0.6/node_modules/marked/lib/marked.esm.mjs +59 -1
- package/es/node_modules/.pnpm/marked@17.0.6/node_modules/marked/lib/marked.esm.mjs.map +1 -1
- package/es/node_modules/.pnpm/turndown-plugin-gfm@1.0.2/node_modules/turndown-plugin-gfm/lib/turndown-plugin-gfm.es.mjs +16 -1
- package/es/node_modules/.pnpm/turndown-plugin-gfm@1.0.2/node_modules/turndown-plugin-gfm/lib/turndown-plugin-gfm.es.mjs.map +1 -1
- package/es/node_modules/.pnpm/turndown@7.2.4/node_modules/turndown/lib/turndown.browser.es.mjs +62 -0
- package/es/node_modules/.pnpm/turndown@7.2.4/node_modules/turndown/lib/turndown.browser.es.mjs.map +1 -0
- package/es/photo-crop-tool.mjs +12 -12
- package/es/photo-crop-tool.mjs.map +1 -1
- package/es/subject/action.mjs +58 -58
- package/es/subject/action.mjs.map +1 -1
- package/es/subject/blank-fill.mjs +80 -80
- package/es/subject/blank-fill.mjs.map +1 -1
- package/es/subject/draft.mjs +1 -1
- package/es/subject/draft.mjs.map +1 -1
- package/es/subject/layout.mjs +4 -4
- package/es/subject/layout.mjs.map +1 -1
- package/es/subject/page-end.mjs +5 -5
- package/es/subject/page-end.mjs.map +1 -1
- package/es/subject/pagination.mjs +1 -1
- package/es/subject/pagination.mjs.map +1 -1
- package/es/subject/runtime.mjs +1 -1
- package/es/subject/runtime.mjs.map +1 -1
- package/es/subject/scale.mjs +53 -50
- package/es/subject/scale.mjs.map +1 -1
- package/es/subject/shared-methods.mjs +1 -1
- package/es/subject/shared-methods.mjs.map +1 -1
- package/es/subject/shared-styles.mjs +53 -15
- package/es/subject/shared-styles.mjs.map +1 -1
- package/es/subject/single-interactions.mjs +2 -0
- package/es/subject/single-interactions.mjs.map +1 -0
- package/es/subject/single-model.mjs +2 -0
- package/es/subject/single-model.mjs.map +1 -0
- package/es/subject/single-state.mjs +2 -0
- package/es/subject/single-state.mjs.map +1 -0
- package/es/subject/single.mjs +177 -177
- package/es/subject/single.mjs.map +1 -1
- package/es/subject/sort-controller.mjs +1 -1
- package/es/subject/sort-controller.mjs.map +1 -1
- package/es/subject/sortable.mjs +13 -13
- package/es/subject/sortable.mjs.map +1 -1
- package/es/subject/sorting-card.mjs +12 -12
- package/es/subject/sorting-card.mjs.map +1 -1
- package/es/subject/subject-shared.mjs +2 -0
- package/es/subject/subject-shared.mjs.map +1 -0
- package/es/subject/text-fill.mjs +73 -73
- package/es/subject/text-fill.mjs.map +1 -1
- package/es/subject/title-prefix.mjs +1 -1
- package/es/subject/title-prefix.mjs.map +1 -1
- package/es/subject/types.mjs +1 -1
- package/es/subject/types.mjs.map +1 -1
- package/lib/base/define.cjs +1 -1
- package/lib/base/define.cjs.map +1 -1
- package/lib/base/uid.cjs +1 -1
- package/lib/base/uid.cjs.map +1 -1
- package/lib/data-chart.cjs +16 -15
- package/lib/data-chart.cjs.map +1 -1
- package/lib/editor/blocksuite-editor.cjs +62 -51
- package/lib/editor/blocksuite-editor.cjs.map +1 -1
- package/lib/editor/content-format.cjs +8 -1
- package/lib/editor/content-format.cjs.map +1 -1
- package/lib/editor/index.cjs +1 -1
- package/lib/editor/index.cjs.map +1 -1
- package/lib/editor/toolbar.cjs +1 -1
- package/lib/editor/toolbar.cjs.map +1 -1
- package/lib/entry-data-chart.cjs +1 -1
- package/lib/entry-editor.cjs +1 -1
- package/lib/entry-file-upload.cjs +1 -1
- package/lib/entry-fixed-action-bar.cjs +1 -1
- package/lib/entry-icon.cjs +1 -1
- package/lib/entry-image-upload.cjs +1 -1
- package/lib/entry-photo-crop-tool.cjs +1 -1
- package/lib/entry-subject.cjs +1 -1
- package/lib/file-upload.cjs +24 -17
- package/lib/file-upload.cjs.map +1 -1
- package/lib/fixed-action-bar.cjs +6 -6
- package/lib/fixed-action-bar.cjs.map +1 -1
- package/lib/icon.cjs +9 -9
- package/lib/icon.cjs.map +1 -1
- package/lib/image-upload.cjs +26 -26
- package/lib/image-upload.cjs.map +1 -1
- package/lib/index.cjs +1 -1
- package/lib/node_modules/.pnpm/marked@17.0.6/node_modules/marked/lib/marked.esm.cjs +59 -1
- package/lib/node_modules/.pnpm/marked@17.0.6/node_modules/marked/lib/marked.esm.cjs.map +1 -1
- package/lib/node_modules/.pnpm/turndown-plugin-gfm@1.0.2/node_modules/turndown-plugin-gfm/lib/turndown-plugin-gfm.es.cjs +16 -1
- package/lib/node_modules/.pnpm/turndown-plugin-gfm@1.0.2/node_modules/turndown-plugin-gfm/lib/turndown-plugin-gfm.es.cjs.map +1 -1
- package/lib/node_modules/.pnpm/turndown@7.2.4/node_modules/turndown/lib/turndown.browser.es.cjs +62 -0
- package/lib/node_modules/.pnpm/turndown@7.2.4/node_modules/turndown/lib/turndown.browser.es.cjs.map +1 -0
- package/lib/photo-crop-tool.cjs +11 -11
- package/lib/photo-crop-tool.cjs.map +1 -1
- package/lib/subject/action.cjs +42 -42
- package/lib/subject/action.cjs.map +1 -1
- package/lib/subject/blank-fill.cjs +80 -80
- package/lib/subject/blank-fill.cjs.map +1 -1
- package/lib/subject/draft.cjs +1 -1
- package/lib/subject/draft.cjs.map +1 -1
- package/lib/subject/layout.cjs +4 -4
- package/lib/subject/layout.cjs.map +1 -1
- package/lib/subject/page-end.cjs +4 -4
- package/lib/subject/page-end.cjs.map +1 -1
- package/lib/subject/pagination.cjs +1 -1
- package/lib/subject/pagination.cjs.map +1 -1
- package/lib/subject/runtime.cjs +1 -1
- package/lib/subject/runtime.cjs.map +1 -1
- package/lib/subject/scale.cjs +53 -50
- package/lib/subject/scale.cjs.map +1 -1
- package/lib/subject/shared-methods.cjs +1 -1
- package/lib/subject/shared-methods.cjs.map +1 -1
- package/lib/subject/shared-styles.cjs +54 -16
- package/lib/subject/shared-styles.cjs.map +1 -1
- package/lib/subject/single-interactions.cjs +2 -0
- package/lib/subject/single-interactions.cjs.map +1 -0
- package/lib/subject/single-model.cjs +2 -0
- package/lib/subject/single-model.cjs.map +1 -0
- package/lib/subject/single-state.cjs +2 -0
- package/lib/subject/single-state.cjs.map +1 -0
- package/lib/subject/single.cjs +177 -177
- package/lib/subject/single.cjs.map +1 -1
- package/lib/subject/sort-controller.cjs +1 -1
- package/lib/subject/sort-controller.cjs.map +1 -1
- package/lib/subject/sortable.cjs +15 -15
- package/lib/subject/sortable.cjs.map +1 -1
- package/lib/subject/sorting-card.cjs +12 -12
- package/lib/subject/sorting-card.cjs.map +1 -1
- package/lib/subject/subject-shared.cjs +2 -0
- package/lib/subject/subject-shared.cjs.map +1 -0
- package/lib/subject/text-fill.cjs +81 -81
- package/lib/subject/text-fill.cjs.map +1 -1
- package/lib/subject/title-prefix.cjs +1 -1
- package/lib/subject/title-prefix.cjs.map +1 -1
- package/lib/subject/types.cjs +1 -1
- package/lib/subject/types.cjs.map +1 -1
- package/package.json +5 -5
- package/types/editor/blocksuite-editor.d.ts +2 -0
- package/types/editor/toolbar.d.ts +1 -1
- package/types/file-upload.d.ts +2 -0
- package/types/subject/blank-fill.d.ts +1 -1
- package/types/subject/runtime.d.ts +1 -1
- package/types/subject/scale.d.ts +1 -1
- package/types/subject/single-interactions.d.ts +46 -0
- package/types/subject/single-model.d.ts +88 -0
- package/types/subject/single-state.d.ts +42 -0
- package/types/subject/single.d.ts +7 -85
- package/types/subject/sortable.d.ts +1 -1
- package/types/subject/subject-shared.d.ts +43 -0
- package/types/subject/text-fill.d.ts +1 -1
- package/README.md +0 -562
- package/es/node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.18_typescript@5.9.2_/node_modules/@iconify/vue/dist/iconify.mjs +0 -2
- package/es/node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.18_typescript@5.9.2_/node_modules/@iconify/vue/dist/iconify.mjs.map +0 -1
- package/es/node_modules/.pnpm/turndown@7.2.4/node_modules/turndown/lib/turndown.es.mjs +0 -2
- package/es/node_modules/.pnpm/turndown@7.2.4/node_modules/turndown/lib/turndown.es.mjs.map +0 -1
- package/es/package.json.mjs +0 -2
- package/es/package.json.mjs.map +0 -1
- package/es/src/alert/index.mjs +0 -2
- package/es/src/alert/index.mjs.map +0 -1
- package/es/src/alert/src/alert.mjs +0 -2
- package/es/src/alert/src/alert.mjs.map +0 -1
- package/es/src/components.mjs +0 -2
- package/es/src/components.mjs.map +0 -1
- package/es/src/data-chart/index.mjs +0 -2
- package/es/src/data-chart/index.mjs.map +0 -1
- package/es/src/defaults.mjs +0 -2
- package/es/src/defaults.mjs.map +0 -1
- package/es/src/dialog/src/dialog.mjs +0 -2
- package/es/src/dialog/src/dialog.mjs.map +0 -1
- package/es/src/feedback-plugin/index.mjs +0 -2
- package/es/src/feedback-plugin/index.mjs.map +0 -1
- package/es/src/file-upload/index.mjs +0 -2
- package/es/src/file-upload/index.mjs.map +0 -1
- package/es/src/icon/index.mjs +0 -2
- package/es/src/icon/index.mjs.map +0 -1
- package/es/src/icon/src/icon.mjs +0 -2
- package/es/src/icon/src/icon.mjs.map +0 -1
- package/es/src/image-upload/index.mjs +0 -2
- package/es/src/image-upload/index.mjs.map +0 -1
- package/es/src/make-installer.mjs +0 -2
- package/es/src/make-installer.mjs.map +0 -1
- package/es/src/message/src/message.mjs +0 -2
- package/es/src/message/src/message.mjs.map +0 -1
- package/es/src/photo-crop-tool/index.mjs +0 -2
- package/es/src/photo-crop-tool/index.mjs.map +0 -1
- package/es/src/tiny-mce-editor/index.mjs +0 -2
- package/es/src/tiny-mce-editor/index.mjs.map +0 -1
- package/es/src/tiny-mce-editor/src/tiny-mce-editor.vue.mjs +0 -2
- package/es/src/tiny-mce-editor/src/tiny-mce-editor.vue.mjs.map +0 -1
- package/es/src/tiny-mce-editor/src/tiny-mce-editor.vue2.mjs +0 -2
- package/es/src/tiny-mce-editor/src/tiny-mce-editor.vue2.mjs.map +0 -1
- package/es/src/ui/button/index.mjs +0 -2
- package/es/src/ui/button/index.mjs.map +0 -1
- package/es/src/ui/checkbox/index.mjs +0 -2
- package/es/src/ui/checkbox/index.mjs.map +0 -1
- package/es/src/ui/dialog/index.mjs +0 -2
- package/es/src/ui/dialog/index.mjs.map +0 -1
- package/es/src/ui/input/index.mjs +0 -2
- package/es/src/ui/input/index.mjs.map +0 -1
- package/es/src/ui/input-number/index.mjs +0 -2
- package/es/src/ui/input-number/index.mjs.map +0 -1
- package/es/src/ui/layout/index.mjs +0 -2
- package/es/src/ui/layout/index.mjs.map +0 -1
- package/es/src/ui/link/index.mjs +0 -2
- package/es/src/ui/link/index.mjs.map +0 -1
- package/es/src/ui/popover/index.mjs +0 -2
- package/es/src/ui/popover/index.mjs.map +0 -1
- package/es/src/ui/radio/index.mjs +0 -2
- package/es/src/ui/radio/index.mjs.map +0 -1
- package/es/src/ui/scrollbar/index.mjs +0 -2
- package/es/src/ui/scrollbar/index.mjs.map +0 -1
- package/es/src/ui/select/index.mjs +0 -2
- package/es/src/ui/select/index.mjs.map +0 -1
- package/es/src/ui/table/index.mjs +0 -2
- package/es/src/ui/table/index.mjs.map +0 -1
- package/es/src/ui/tag/index.mjs +0 -2
- package/es/src/ui/tag/index.mjs.map +0 -1
- package/es/src/wc-bridge.mjs +0 -2
- package/es/src/wc-bridge.mjs.map +0 -1
- package/es/src/withInstall.mjs +0 -2
- package/es/src/withInstall.mjs.map +0 -1
- package/lib/node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.18_typescript@5.9.2_/node_modules/@iconify/vue/dist/iconify.cjs +0 -2
- package/lib/node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.18_typescript@5.9.2_/node_modules/@iconify/vue/dist/iconify.cjs.map +0 -1
- package/lib/node_modules/.pnpm/turndown@7.2.4/node_modules/turndown/lib/turndown.es.cjs +0 -2
- package/lib/node_modules/.pnpm/turndown@7.2.4/node_modules/turndown/lib/turndown.es.cjs.map +0 -1
- package/lib/package.json.cjs +0 -2
- package/lib/package.json.cjs.map +0 -1
- package/lib/src/alert/index.cjs +0 -2
- package/lib/src/alert/index.cjs.map +0 -1
- package/lib/src/alert/src/alert.cjs +0 -2
- package/lib/src/alert/src/alert.cjs.map +0 -1
- package/lib/src/components.cjs +0 -2
- package/lib/src/components.cjs.map +0 -1
- package/lib/src/data-chart/index.cjs +0 -2
- package/lib/src/data-chart/index.cjs.map +0 -1
- package/lib/src/defaults.cjs +0 -2
- package/lib/src/defaults.cjs.map +0 -1
- package/lib/src/dialog/src/dialog.cjs +0 -2
- package/lib/src/dialog/src/dialog.cjs.map +0 -1
- package/lib/src/feedback-plugin/index.cjs +0 -2
- package/lib/src/feedback-plugin/index.cjs.map +0 -1
- package/lib/src/file-upload/index.cjs +0 -2
- package/lib/src/file-upload/index.cjs.map +0 -1
- package/lib/src/icon/index.cjs +0 -2
- package/lib/src/icon/index.cjs.map +0 -1
- package/lib/src/icon/src/icon.cjs +0 -2
- package/lib/src/icon/src/icon.cjs.map +0 -1
- package/lib/src/image-upload/index.cjs +0 -2
- package/lib/src/image-upload/index.cjs.map +0 -1
- package/lib/src/make-installer.cjs +0 -2
- package/lib/src/make-installer.cjs.map +0 -1
- package/lib/src/message/src/message.cjs +0 -2
- package/lib/src/message/src/message.cjs.map +0 -1
- package/lib/src/photo-crop-tool/index.cjs +0 -2
- package/lib/src/photo-crop-tool/index.cjs.map +0 -1
- package/lib/src/tiny-mce-editor/index.cjs +0 -2
- package/lib/src/tiny-mce-editor/index.cjs.map +0 -1
- package/lib/src/tiny-mce-editor/src/tiny-mce-editor.vue.cjs +0 -2
- package/lib/src/tiny-mce-editor/src/tiny-mce-editor.vue.cjs.map +0 -1
- package/lib/src/tiny-mce-editor/src/tiny-mce-editor.vue2.cjs +0 -2
- package/lib/src/tiny-mce-editor/src/tiny-mce-editor.vue2.cjs.map +0 -1
- package/lib/src/ui/button/index.cjs +0 -2
- package/lib/src/ui/button/index.cjs.map +0 -1
- package/lib/src/ui/checkbox/index.cjs +0 -2
- package/lib/src/ui/checkbox/index.cjs.map +0 -1
- package/lib/src/ui/dialog/index.cjs +0 -2
- package/lib/src/ui/dialog/index.cjs.map +0 -1
- package/lib/src/ui/input/index.cjs +0 -2
- package/lib/src/ui/input/index.cjs.map +0 -1
- package/lib/src/ui/input-number/index.cjs +0 -2
- package/lib/src/ui/input-number/index.cjs.map +0 -1
- package/lib/src/ui/layout/index.cjs +0 -2
- package/lib/src/ui/layout/index.cjs.map +0 -1
- package/lib/src/ui/link/index.cjs +0 -2
- package/lib/src/ui/link/index.cjs.map +0 -1
- package/lib/src/ui/popover/index.cjs +0 -2
- package/lib/src/ui/popover/index.cjs.map +0 -1
- package/lib/src/ui/radio/index.cjs +0 -2
- package/lib/src/ui/radio/index.cjs.map +0 -1
- package/lib/src/ui/scrollbar/index.cjs +0 -2
- package/lib/src/ui/scrollbar/index.cjs.map +0 -1
- package/lib/src/ui/select/index.cjs +0 -2
- package/lib/src/ui/select/index.cjs.map +0 -1
- package/lib/src/ui/table/index.cjs +0 -2
- package/lib/src/ui/table/index.cjs.map +0 -1
- package/lib/src/ui/tag/index.cjs +0 -2
- package/lib/src/ui/tag/index.cjs.map +0 -1
- package/lib/src/wc-bridge.cjs +0 -2
- package/lib/src/wc-bridge.cjs.map +0 -1
- package/lib/src/withInstall.cjs +0 -2
- package/lib/src/withInstall.cjs.map +0 -1
- package/types/index.d.ts.map +0 -1
- package/types/src/alert/index.d.ts +0 -66
- package/types/src/alert/index.d.ts.map +0 -1
- package/types/src/alert/src/alert.d.ts +0 -73
- package/types/src/alert/src/alert.d.ts.map +0 -1
- package/types/src/components.d.ts +0 -10
- package/types/src/components.d.ts.map +0 -1
- package/types/src/data-chart/index.d.ts +0 -13
- package/types/src/data-chart/index.d.ts.map +0 -1
- package/types/src/defaults.d.ts +0 -6
- package/types/src/defaults.d.ts.map +0 -1
- package/types/src/dialog/index.d.ts +0 -3
- package/types/src/dialog/index.d.ts.map +0 -1
- package/types/src/dialog/src/dialog.d.ts +0 -25
- package/types/src/dialog/src/dialog.d.ts.map +0 -1
- package/types/src/feedback-plugin/index.d.ts +0 -9
- package/types/src/feedback-plugin/index.d.ts.map +0 -1
- package/types/src/file-upload/index.d.ts +0 -12
- package/types/src/file-upload/index.d.ts.map +0 -1
- package/types/src/icon/index.d.ts +0 -56
- package/types/src/icon/index.d.ts.map +0 -1
- package/types/src/icon/src/icon.d.ts +0 -62
- package/types/src/icon/src/icon.d.ts.map +0 -1
- package/types/src/image-upload/index.d.ts +0 -12
- package/types/src/image-upload/index.d.ts.map +0 -1
- package/types/src/make-installer.d.ts +0 -6
- package/types/src/make-installer.d.ts.map +0 -1
- package/types/src/message/index.d.ts +0 -3
- package/types/src/message/index.d.ts.map +0 -1
- package/types/src/message/src/message.d.ts +0 -21
- package/types/src/message/src/message.d.ts.map +0 -1
- package/types/src/message/src/toaster.vue.d.ts +0 -3
- package/types/src/message/src/toaster.vue.d.ts.map +0 -1
- package/types/src/photo-crop-tool/index.d.ts +0 -12
- package/types/src/photo-crop-tool/index.d.ts.map +0 -1
- package/types/src/subject-action/index.d.ts +0 -93
- package/types/src/subject-action/index.d.ts.map +0 -1
- package/types/src/subject-action/src/subject-action.vue.d.ts +0 -92
- package/types/src/subject-action/src/subject-action.vue.d.ts.map +0 -1
- package/types/src/subject-layout/index.d.ts +0 -30
- package/types/src/subject-layout/index.d.ts.map +0 -1
- package/types/src/subject-layout/src/subject-layout.vue.d.ts +0 -20
- package/types/src/subject-layout/src/subject-layout.vue.d.ts.map +0 -1
- package/types/src/subject-list/index.d.ts +0 -20
- package/types/src/subject-list/index.d.ts.map +0 -1
- package/types/src/subject-list/src/components/SubjectPageEnd.vue.d.ts +0 -24
- package/types/src/subject-list/src/components/SubjectPageEnd.vue.d.ts.map +0 -1
- package/types/src/subject-list/src/components/subject-blank-fill.vue.d.ts +0 -32
- package/types/src/subject-list/src/components/subject-blank-fill.vue.d.ts.map +0 -1
- package/types/src/subject-list/src/components/subject-scale.vue.d.ts +0 -29
- package/types/src/subject-list/src/components/subject-scale.vue.d.ts.map +0 -1
- package/types/src/subject-list/src/components/subject-single.vue.d.ts +0 -37
- package/types/src/subject-list/src/components/subject-single.vue.d.ts.map +0 -1
- package/types/src/subject-list/src/components/subject-text-fill.vue.d.ts +0 -34
- package/types/src/subject-list/src/components/subject-text-fill.vue.d.ts.map +0 -1
- package/types/src/subject-list/src/subject-list.vue.d.ts +0 -21
- package/types/src/subject-list/src/subject-list.vue.d.ts.map +0 -1
- package/types/src/subject-type/index.d.ts +0 -8
- package/types/src/subject-type/index.d.ts.map +0 -1
- package/types/src/subject-type/src/subject-type.vue.d.ts +0 -7
- package/types/src/subject-type/src/subject-type.vue.d.ts.map +0 -1
- package/types/src/tiny-mce-editor/index.d.ts +0 -20
- package/types/src/tiny-mce-editor/index.d.ts.map +0 -1
- package/types/src/tiny-mce-editor/src/tiny-mce-editor.vue.d.ts +0 -32
- package/types/src/tiny-mce-editor/src/tiny-mce-editor.vue.d.ts.map +0 -1
- package/types/src/ui/button/index.d.ts +0 -96
- package/types/src/ui/button/index.d.ts.map +0 -1
- package/types/src/ui/checkbox/index.d.ts +0 -111
- package/types/src/ui/checkbox/index.d.ts.map +0 -1
- package/types/src/ui/dialog/index.d.ts +0 -134
- package/types/src/ui/dialog/index.d.ts.map +0 -1
- package/types/src/ui/index.d.ts +0 -16
- package/types/src/ui/index.d.ts.map +0 -1
- package/types/src/ui/input/index.d.ts +0 -132
- package/types/src/ui/input/index.d.ts.map +0 -1
- package/types/src/ui/input-number/index.d.ts +0 -106
- package/types/src/ui/input-number/index.d.ts.map +0 -1
- package/types/src/ui/layout/index.d.ts +0 -373
- package/types/src/ui/layout/index.d.ts.map +0 -1
- package/types/src/ui/link/index.d.ts +0 -57
- package/types/src/ui/link/index.d.ts.map +0 -1
- package/types/src/ui/popover/index.d.ts +0 -89
- package/types/src/ui/popover/index.d.ts.map +0 -1
- package/types/src/ui/radio/index.d.ts +0 -84
- package/types/src/ui/radio/index.d.ts.map +0 -1
- package/types/src/ui/scrollbar/index.d.ts +0 -35
- package/types/src/ui/scrollbar/index.d.ts.map +0 -1
- package/types/src/ui/select/index.d.ts +0 -113
- package/types/src/ui/select/index.d.ts.map +0 -1
- package/types/src/ui/table/index.d.ts +0 -152
- package/types/src/ui/table/index.d.ts.map +0 -1
- package/types/src/ui/tag/index.d.ts +0 -69
- package/types/src/ui/tag/index.d.ts.map +0 -1
- package/types/src/wc-bridge.d.ts +0 -23
- package/types/src/wc-bridge.d.ts.map +0 -1
- package/types/src/withInstall.d.ts +0 -4
- package/types/src/withInstall.d.ts.map +0 -1
- package/types/tsconfig.tsbuildinfo +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocksuite-editor.mjs","sources":["../../../../packages/components/src/editor/blocksuite-editor.ts"],"sourcesContent":["import { Editor, Extension, mergeAttributes, Node as TiptapNode } from '@tiptap/core'\nimport Blockquote from '@tiptap/extension-blockquote'\nimport Bold from '@tiptap/extension-bold'\nimport BulletList from '@tiptap/extension-bullet-list'\nimport Code from '@tiptap/extension-code'\nimport Document from '@tiptap/extension-document'\nimport Heading from '@tiptap/extension-heading'\nimport History from '@tiptap/extension-history'\nimport HorizontalRule from '@tiptap/extension-horizontal-rule'\nimport Image from '@tiptap/extension-image'\nimport Italic from '@tiptap/extension-italic'\nimport Link from '@tiptap/extension-link'\nimport ListItem from '@tiptap/extension-list-item'\nimport OrderedList from '@tiptap/extension-ordered-list'\nimport Paragraph from '@tiptap/extension-paragraph'\nimport Placeholder from '@tiptap/extension-placeholder'\nimport Strike from '@tiptap/extension-strike'\nimport { Table } from '@tiptap/extension-table'\nimport { TableCell } from '@tiptap/extension-table-cell'\nimport { TableHeader } from '@tiptap/extension-table-header'\nimport { TableRow } from '@tiptap/extension-table-row'\nimport Text from '@tiptap/extension-text'\nimport TextAlign from '@tiptap/extension-text-align'\nimport Underline from '@tiptap/extension-underline'\nimport { css, html, LitElement } from 'lit'\nimport type { EditorToolbarItem } from './toolbar'\nimport { property, state } from 'lit/decorators.js'\nimport {\n EMPTY_EDITOR_HTML,\n transformIncomingContentByFormat,\n transformOutgoingContentByFormat,\n} from './content-format'\nimport {\n DEFAULT_EDITOR_TOOLBAR,\n SIMPLE_EDITOR_TOOLBAR,\n parseEditorToolbarItems,\n} from './toolbar'\nimport type {\n ContentTransform,\n ImageUploadHandler,\n QxsBlocksuiteEditorContentFormat,\n QxsBlocksuiteEditorContentSnapshot,\n QxsBlocksuiteEditorHeaderToolbarLabelKey,\n QxsBlocksuiteEditorHeaderToolbarLabels,\n QxsBlocksuiteEditorImageUploadErrorDetail,\n QxsBlocksuiteEditorToolbarPreset,\n ToolbarMode,\n ToolbarPosition,\n} from './types'\nimport { safeCustomElement } from '../base/define'\n\ntype SlashInlineMark = 'bold' | 'italic' | 'underline' | 'strike' | 'code'\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n taskList: {\n toggleTaskList: () => ReturnType\n }\n }\n}\n\nconst DEFAULT_IMAGE_WIDTH = 560\nconst MIN_IMAGE_WIDTH = 24\nconst DEFAULT_HEADER_PLACEHOLDER = '输入内容'\nconst DEFAULT_SLASH_PLACEHOLDER = '输入 / 唤出快捷命令'\nconst DEFAULT_MIN_HEIGHT = '80px'\nconst HEADER_TOOLBAR_LABEL_KEYS = new Set<QxsBlocksuiteEditorHeaderToolbarLabelKey>([\n 'bold',\n 'italic',\n 'underline',\n 'strike',\n 'code',\n 'link',\n 'image',\n 'bulletList',\n 'orderedList',\n 'taskList',\n 'blockquote',\n 'table',\n])\n\nconst TaskList = TiptapNode.create({\n name: 'taskList',\n group: 'block list',\n content: 'taskItem+',\n defining: true,\n\n parseHTML() {\n return [{ tag: 'ul[data-type=\"taskList\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['ul', mergeAttributes(HTMLAttributes, { 'data-type': 'taskList' }), 0]\n },\n\n addCommands() {\n return {\n toggleTaskList: () => ({ commands }) => commands.toggleList(this.name, 'taskItem'),\n }\n },\n})\n\nconst TaskItem = TiptapNode.create({\n name: 'taskItem',\n defining: true,\n content: 'paragraph block*',\n\n addAttributes() {\n return {\n checked: {\n default: false,\n parseHTML: element => element.getAttribute('data-checked') === 'true',\n renderHTML: attributes => ({ 'data-checked': String(Boolean(attributes.checked)) }),\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'li[data-type=\"taskItem\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n const checked = Boolean(HTMLAttributes.checked)\n\n return [\n 'li',\n mergeAttributes(HTMLAttributes, { 'data-type': 'taskItem' }),\n [\n 'label',\n { contenteditable: 'false' },\n ['input', { type: 'checkbox', checked: checked ? 'checked' : null }],\n ['span'],\n ],\n ['div', 0],\n ]\n },\n\n addKeyboardShortcuts() {\n return {\n Enter: () => this.editor.commands.splitListItem(this.name),\n Tab: () => this.editor.commands.sinkListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n },\n})\n\nconst ExtendedImage = Image.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n width: {\n default: null,\n parseHTML: (element) => {\n const attr = element.getAttribute('width')\n const value = Number(attr)\n return Number.isFinite(value) && value > 0 ? value : null\n },\n renderHTML: attributes => attributes.width ? { width: String(attributes.width) } : {},\n },\n align: {\n default: 'left',\n parseHTML: element => element.getAttribute('data-align') || 'left',\n renderHTML: attributes => attributes.align ? { 'data-align': String(attributes.align) } : {},\n },\n }\n },\n\n renderHTML({ HTMLAttributes }) {\n const width = Number(HTMLAttributes.width)\n\n const style = [\n 'max-width:100%',\n 'height:auto',\n Number.isFinite(width) && width > 0 ? `width:${width}px` : '',\n HTMLAttributes.style || '',\n ]\n .filter(Boolean)\n .join(';')\n\n return ['img', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { style })]\n },\n})\n\n@safeCustomElement('qxs-blocksuite-editor')\nexport class QxsBlocksuiteEditor extends LitElement {\n static styles = css`\n :host {\n display: block;\n font-family: inherit;\n }\n\n .editor-wrapper {\n border: 1px solid #e3e3e3;\n border-radius: 12px;\n background: #fff;\n overflow: visible;\n position: relative;\n min-height: var(--qxs-editor-min-height, 80px);\n }\n\n .editor-wrapper:focus-within {\n border-color: var(--qxs-color-primary, #3D61E3);\n }\n\n .editor-wrapper.preview {\n border: none;\n border-radius: 0;\n background: transparent;\n }\n\n .editor-wrapper.preview .editor-content {\n padding: 8px 12px;\n min-height: unset;\n max-height: none;\n overflow: visible;\n }\n\n .editor-wrapper.toolbar-bottom .editor-header {\n border-bottom: none;\n border-top: 1px solid transparent;\n }\n\n .editor-wrapper.toolbar-bottom .editor-header.is-visible {\n border-top-color: #eef1f5;\n border-bottom-color: transparent;\n }\n\n .editor-header {\n max-height: 0;\n opacity: 0;\n overflow: hidden;\n padding: 0 16px;\n border-bottom: 1px solid transparent;\n transition:\n max-height 0.24s ease,\n opacity 0.18s ease,\n padding 0.24s ease,\n border-color 0.24s ease;\n }\n\n .editor-header.is-visible {\n max-height: 132px;\n opacity: 1;\n overflow: visible;\n padding: 10px 12px;\n border-bottom-color: #eef1f5;\n }\n\n .editor-header__inner {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n overflow: visible;\n }\n\n .editor-content {\n padding: 12px 16px;\n min-height: var(--qxs-editor-min-height, 80px);\n max-height: var(--qxs-editor-max-height, none);\n overflow-y: var(--qxs-editor-overflow-y, visible);\n cursor: text;\n }\n\n .editor-content:empty::before {\n content: attr(data-empty-hint);\n color: #c0c0c0;\n pointer-events: none;\n display: block;\n padding-top: 28px;\n text-align: center;\n }\n\n .editor-wrapper:not(.preview) .ProseMirror {\n min-height: var(--qxs-editor-min-height, 80px);\n }\n\n .editor-footer {\n display: flex;\n justify-content: flex-end;\n padding: 0 16px 12px;\n color: #909399;\n font-size: 12px;\n line-height: 1;\n }\n\n .ProseMirror p.is-editor-empty:first-child::before {\n content: attr(data-placeholder);\n color: #c0c0c0;\n pointer-events: none;\n float: left;\n height: 0;\n }\n\n .ProseMirror p.is-empty:only-child::before,\n .ProseMirror p.is-empty:only-child > br:first-child + *::before {\n content: attr(data-placeholder);\n color: #c0c0c0;\n pointer-events: none;\n float: left;\n height: 0;\n }\n\n .editor-wrapper.loading {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n background: #fafafa;\n }\n\n .loading-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n color: #909399;\n font-size: 14px;\n }\n\n .loading-spinner {\n width: 24px;\n height: 24px;\n border: 2px solid #e3e3e3;\n border-top-color: var(--qxs-color-primary, #3D61E3);\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .ProseMirror {\n outline: none;\n line-height: 1.7;\n color: #37352f;\n font-size: 15px;\n }\n\n .ProseMirror > * + * {\n margin-top: 0.5em;\n }\n\n .ProseMirror > *:first-child {\n margin-top: 0 !important;\n }\n\n .ProseMirror p {\n margin: 0;\n }\n\n .ProseMirror h1 {\n font-size: 1.875em;\n font-weight: 700;\n margin: 0 0 0.25em;\n line-height: 1.3;\n }\n\n .ProseMirror > h1:first-child {\n margin-top: 0 !important;\n line-height: 1.15;\n }\n\n .ProseMirror > p:first-child {\n margin-top: 0 !important;\n }\n\n .ProseMirror h2 {\n font-size: 1.5em;\n font-weight: 600;\n margin: 0.5em 0 0.25em;\n line-height: 1.3;\n }\n\n .ProseMirror h3 {\n font-size: 1.25em;\n font-weight: 600;\n margin: 0.5em 0 0.25em;\n line-height: 1.3;\n }\n\n .ProseMirror ul,\n .ProseMirror ol {\n padding-left: 1.5em;\n margin: 0;\n }\n\n .ProseMirror ul[data-type=\"taskList\"] {\n padding-left: 0;\n list-style: none;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n list-style: none;\n margin: 0.2em 0;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] > label {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 28px;\n flex: 0 0 18px;\n cursor: pointer;\n user-select: none;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] > label > input {\n width: 14px;\n height: 14px;\n margin: 0;\n cursor: pointer;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] > label > span {\n display: none;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] > div {\n flex: 1;\n min-width: 0;\n }\n\n .ProseMirror li[data-type=\"taskItem\"][data-checked=\"true\"] > div p {\n color: #8a8f98;\n text-decoration: line-through;\n }\n\n .ProseMirror li {\n margin: 0.1em 0;\n }\n\n .ProseMirror li::marker {\n color: #37352f;\n }\n\n .ProseMirror strong {\n font-weight: 700;\n }\n\n .ProseMirror em {\n font-style: italic;\n font-synthesis: none;\n transform: skewX(-12deg);\n display: inline-block;\n }\n\n .ProseMirror u {\n text-decoration: underline;\n }\n\n .ProseMirror s {\n text-decoration: line-through;\n color: #787774;\n }\n\n .ProseMirror code {\n background: rgba(135, 131, 120, 0.14);\n color: #eb5757;\n padding: 2px 4px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', Menlo, Consolas, monospace;\n font-size: 85%;\n }\n\n .ProseMirror pre {\n background: #f6f6f7;\n border-radius: 8px;\n padding: 12px 16px;\n overflow-x: auto;\n }\n\n .ProseMirror pre code {\n background: none;\n padding: 0;\n color: #37352f;\n }\n\n .ProseMirror blockquote {\n border-left: 3px solid #e3e3e3;\n padding-left: 1em;\n margin: 0.75em 0;\n color: #787774;\n }\n\n .ProseMirror hr {\n border: none;\n border-top: 1px solid #e3e3e3;\n margin: 1.5em 0;\n }\n\n .ProseMirror img {\n max-width: 100%;\n height: auto;\n border-radius: 8px;\n }\n\n .ProseMirror img[data-align=\"left\"] {\n display: block !important;\n margin: 16px auto 16px 0 !important;\n }\n\n .ProseMirror img[data-align=\"center\"] {\n display: block !important;\n margin: 16px auto !important;\n }\n\n .ProseMirror img[data-align=\"right\"] {\n display: block !important;\n margin: 16px 0 16px auto !important;\n }\n\n .ProseMirror a {\n color: var(--qxs-color-primary, #3D61E3);\n text-decoration: underline;\n cursor: pointer;\n }\n\n .ProseMirror img.ProseMirror-selectednode {\n outline: 2px solid var(--qxs-color-primary, #3D61E3);\n outline-offset: 2px;\n box-shadow: 0 0 0 4px rgba(61, 97, 227, 0.12);\n }\n\n /* Table styles */\n .ProseMirror table {\n border-collapse: collapse;\n width: 100%;\n margin: 1em 0;\n border: 1px solid #e3e3e3;\n border-radius: 8px;\n overflow: hidden;\n }\n\n .ProseMirror th,\n .ProseMirror td {\n border: 1px solid #e3e3e3;\n padding: 8px 12px;\n text-align: left;\n vertical-align: top;\n }\n\n .ProseMirror th {\n background: #fafafa;\n font-weight: 600;\n }\n\n .ProseMirror .selectedCell {\n background: rgba(30, 150, 252, 0.1);\n }\n\n /* Table Cell Toolbar */\n .table-cell-toolbar {\n position: absolute;\n z-index: 50;\n display: flex;\n gap: 2px;\n padding: 4px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n }\n\n .table-cell-toolbar-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #606266;\n transition: all 0.15s;\n }\n\n .table-cell-toolbar-btn:hover {\n background: #ecf5ff;\n color: var(--qxs-color-primary, #3D61E3);\n }\n\n .table-cell-toolbar-btn.danger:hover {\n background: #fef0f0;\n color: #f56c6c;\n }\n\n /* Bubble Menu */\n .bubble-menu {\n position: absolute;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 4px 6px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n z-index: 100;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.15s, visibility 0.15s, transform 0.15s;\n transform: translateY(4px);\n max-width: calc(100vw - 40px);\n }\n\n .bubble-menu.is-visible {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n }\n\n .bubble-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: #37352f;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.15s;\n position: relative;\n }\n\n .bubble-btn.has-label {\n gap: 6px;\n width: auto;\n padding: 0 10px;\n white-space: nowrap;\n }\n\n .bubble-btn:hover {\n background: rgba(55, 53, 47, 0.08);\n }\n\n .bubble-btn.is-active {\n background: var(--qxs-color-primary, #3D61E3);\n color: #fff;\n }\n\n .bubble-btn.danger:hover {\n background: #fef0f0;\n color: #f56c6c;\n }\n\n .bubble-btn svg {\n width: 16px;\n height: 16px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n flex: 0 0 auto;\n }\n\n .bubble-btn__label {\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n }\n\n .bubble-divider {\n width: 1px;\n height: 16px;\n background: #e3e3e3;\n margin: 0 3px;\n }\n\n /* Dropdown */\n .bubble-dropdown {\n position: relative;\n }\n\n .bubble-dropdown-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 0 6px;\n height: 28px;\n border: none;\n background: transparent;\n color: #37352f;\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n font-family: inherit;\n transition: all 0.15s;\n white-space: nowrap;\n }\n\n .bubble-dropdown-btn.has-label {\n gap: 6px;\n padding: 0 10px;\n }\n\n .bubble-dropdown-btn:hover {\n background: rgba(55, 53, 47, 0.08);\n }\n\n .bubble-dropdown-btn svg {\n width: 12px;\n height: 12px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n .bubble-dropdown-btn__label {\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n }\n\n .bubble-dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n margin-top: 4px;\n min-width: 120px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n padding: 4px;\n opacity: 0;\n visibility: hidden;\n transform: translateY(-4px);\n transition: all 0.15s;\n z-index: 101;\n }\n\n .bubble-dropdown:hover .bubble-dropdown-menu,\n .bubble-dropdown.is-open .bubble-dropdown-menu {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n }\n\n .bubble-dropdown-item {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 6px 8px;\n border: none;\n background: transparent;\n color: #37352f;\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n font-family: inherit;\n text-align: left;\n transition: all 0.15s;\n }\n\n .bubble-dropdown-item:hover {\n background: rgba(55, 53, 47, 0.08);\n }\n\n .bubble-dropdown-item.is-active {\n background: var(--qxs-color-primary, #3D61E3);\n color: #fff;\n }\n\n .bubble-dropdown-item svg {\n width: 16px;\n height: 16px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n .image-input {\n display: none;\n }\n\n .table-grid-preview {\n display: grid;\n grid-template-columns: repeat(10, 18px);\n gap: 2px;\n padding: 8px;\n }\n\n .table-grid-preview .table-cell {\n width: 18px;\n height: 18px;\n border: 1px solid #e3e3e3;\n border-radius: 2px;\n background: #fff;\n cursor: pointer;\n transition: all 0.1s;\n }\n\n .table-grid-preview .table-cell:hover {\n background: rgba(30, 150, 252, 0.3);\n border-color: var(--qxs-color-primary, #3D61E3);\n }\n\n .table-grid-preview .table-cell.selected {\n background: rgba(30, 150, 252, 0.15);\n border-color: rgba(30, 150, 252, 0.5);\n }\n\n .table-size-hint {\n text-align: center;\n padding: 4px 8px 6px;\n font-size: 10px;\n color: #8c8c8c;\n }\n\n .image-size-control {\n display: flex;\n align-items: center;\n gap: 6px;\n padding-left: 8px;\n margin-left: 2px;\n border-left: 1px solid #e3e3e3;\n white-space: nowrap;\n }\n\n .image-size-label {\n font-size: 12px;\n color: #7a7f88;\n }\n\n .image-size-range {\n width: 72px;\n height: 26px;\n padding: 0 8px;\n border: 1px solid #d8dde6;\n border-radius: 6px;\n font-size: 12px;\n color: #37352f;\n background: #fff;\n outline: none;\n }\n\n .image-size-range:focus {\n border-color: var(--qxs-color-primary, #3D61E3);\n }\n\n .link-editor {\n position: absolute;\n z-index: 120;\n display: grid;\n gap: 8px;\n min-width: 320px;\n padding: 10px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 10px;\n box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14);\n }\n\n .link-editor__field {\n display: grid;\n gap: 4px;\n }\n\n .link-editor__label {\n font-size: 12px;\n color: #6b7280;\n line-height: 1;\n }\n\n .link-editor__input {\n min-width: 0;\n height: 32px;\n padding: 0 10px;\n border: 1px solid #d8dde6;\n border-radius: 8px;\n outline: none;\n font-size: 13px;\n color: #37352f;\n background: #fff;\n }\n\n .link-editor__input:focus {\n border-color: var(--qxs-color-primary, #3D61E3);\n }\n\n .link-editor__actions {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .link-editor__action {\n height: 32px;\n padding: 0 12px;\n border: 1px solid #d8dde6;\n border-radius: 8px;\n background: #fff;\n color: #4b5563;\n font-size: 12px;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n }\n\n .link-editor__action:hover {\n border-color: #c3cad5;\n background: #f8fafc;\n }\n\n .link-editor__action.primary {\n border-color: var(--qxs-color-primary, #3D61E3);\n background: var(--qxs-color-primary, #3D61E3);\n color: #fff;\n }\n\n .link-editor__action.danger {\n color: #f56c6c;\n }\n\n /* Image Toolbar */\n .image-toolbar {\n position: absolute;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 4px 6px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 6px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n z-index: 100;\n transform: translateX(-50%);\n }\n\n .image-toolbar-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #595959;\n transition: all 0.15s;\n }\n\n .image-toolbar-btn:hover {\n background: #f5f5f5;\n color: var(--qxs-color-primary, #3D61E3);\n }\n\n .image-toolbar-btn.danger:hover {\n background: #fff1f0;\n color: #ff4d4f;\n }\n\n .image-toolbar-btn svg {\n width: 16px;\n height: 16px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n .image-toolbar-divider {\n width: 1px;\n height: 20px;\n background: #e3e3e3;\n margin: 0 4px;\n }\n\n .image-control-label {\n display: inline-flex;\n align-items: center;\n padding: 0 4px;\n font-size: 12px;\n color: #909399;\n user-select: none;\n white-space: nowrap;\n }\n\n /* Image More Menu */\n .image-more-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n padding: 4px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 6px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n z-index: 101;\n min-width: 120px;\n }\n\n .image-more-menu-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: none;\n background: transparent;\n width: 100%;\n text-align: left;\n font-size: 13px;\n color: #595959;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .image-more-menu-item:hover {\n background: #f5f5f5;\n color: var(--qxs-color-primary, #3D61E3);\n }\n\n .image-more-menu-item svg {\n width: 14px;\n height: 14px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n /* Selected Image */\n .ProseMirror img.selected {\n outline: 2px solid var(--qxs-color-primary, #3D61E3);\n outline-offset: 2px;\n }\n `\n\n @property({ type: String, attribute: 'content' })\n content = ''\n\n @property({ type: String, attribute: 'model-value' })\n 'model-value' = ''\n\n @property({ type: String, attribute: 'placeholder' })\n placeholder = DEFAULT_HEADER_PLACEHOLDER\n\n @property({ type: String, attribute: 'toolbar-mode' })\n 'toolbar-mode': ToolbarMode = 'header'\n\n @property({ attribute: 'toolbar' })\n toolbar: string | EditorToolbarItem[] = ''\n\n @property({ type: String, attribute: 'toolbar-preset' })\n 'toolbar-preset': QxsBlocksuiteEditorToolbarPreset = 'full'\n\n @property({ attribute: 'header-toolbar-labels' })\n 'header-toolbar-labels': string | QxsBlocksuiteEditorHeaderToolbarLabels = ''\n\n @property({ type: String, attribute: 'header-always-visible' })\n 'header-always-visible': boolean | string = 'false'\n\n @property({ type: String, attribute: 'use-model' })\n 'use-model': boolean | string = 'false'\n\n @property({ type: String, attribute: 'readonly' })\n readonly: boolean | string = 'false'\n\n @property({ type: String, attribute: 'preview' })\n preview: boolean | string = 'false'\n\n @property({ attribute: 'editable' })\n editable: boolean | string | null = null\n\n @property({ type: String, attribute: 'min-height' })\n 'min-height' = DEFAULT_MIN_HEIGHT\n\n @property({ type: String, attribute: 'max-height' })\n 'max-height' = ''\n\n @property({ type: String, attribute: 'show-character-count' })\n 'show-character-count': boolean | string = 'false'\n\n @property({ type: String, attribute: 'toolbar-position' })\n 'toolbar-position': ToolbarPosition = 'top'\n\n @property({ type: String, attribute: 'custom-styles' })\n 'custom-styles' = ''\n\n @property({ type: String, attribute: 'content-format' })\n 'content-format': QxsBlocksuiteEditorContentFormat = 'html'\n\n @property({ type: Object, attribute: 'deserialize-content' })\n 'deserialize-content': ContentTransform | null = null\n\n @property({ type: Object, attribute: 'serialize-content' })\n 'serialize-content': ContentTransform | null = null\n\n private _injectedStyleEl: HTMLStyleElement | null = null\n\n private _injectCustomStyles() {\n const shadow = this.shadowRoot\n if (!shadow) { return }\n\n if (this._injectedStyleEl) {\n this._injectedStyleEl.remove()\n this._injectedStyleEl = null\n }\n\n if (!this['custom-styles']) { return }\n\n const styleEl = document.createElement('style')\n styleEl.textContent = this['custom-styles']\n shadow.appendChild(styleEl)\n this._injectedStyleEl = styleEl\n }\n\n private get _useModelValue(): boolean {\n return this['use-model'] === true || this['use-model'] === 'true' || this['use-model'] === '' || this.hasAttribute('use-model')\n }\n\n private get _readonlyValue(): boolean {\n return this.readonly !== false && this.readonly !== 'false'\n }\n\n private get _previewValue(): boolean {\n return this.preview !== false && this.preview !== 'false'\n }\n\n private get _editableValue(): boolean | null {\n if (this.editable === null || this.editable === undefined) {\n return null\n }\n\n return this.editable !== false && this.editable !== 'false'\n }\n\n private get _isEditable(): boolean {\n if (this._previewValue) {\n return false\n }\n\n if (this._editableValue !== null) {\n return this._editableValue\n }\n\n return !this._readonlyValue\n }\n\n private get _toolbarModeValue(): ToolbarMode {\n return this['toolbar-mode'] === 'header' ? 'header' : 'slash'\n }\n\n private get _headerAlwaysVisibleValue(): boolean {\n return this['header-always-visible'] === true\n || this['header-always-visible'] === 'true'\n || this['header-always-visible'] === ''\n || this.hasAttribute('header-always-visible')\n }\n\n private get _toolbarPositionValue(): ToolbarPosition {\n return this['toolbar-position'] === 'bottom' ? 'bottom' : 'top'\n }\n\n private get _toolbarPresetValue(): QxsBlocksuiteEditorToolbarPreset {\n if (this['toolbar-preset'] === 'simple') {\n return 'simple'\n }\n\n if (this['toolbar-preset'] === 'none') {\n return 'none'\n }\n\n return 'full'\n }\n\n private get _contentFormatValue(): QxsBlocksuiteEditorContentFormat {\n if (this['content-format'] === 'markdown') {\n return 'markdown'\n }\n\n if (this['content-format'] === 'custom') {\n return 'custom'\n }\n\n return 'html'\n }\n\n private get _showCharacterCountValue(): boolean {\n return this['show-character-count'] === true\n || this['show-character-count'] === 'true'\n || this['show-character-count'] === ''\n || this.hasAttribute('show-character-count')\n }\n\n private get _resolvedMinHeight(): string {\n return this['min-height']?.trim() || DEFAULT_MIN_HEIGHT\n }\n\n private get _resolvedMaxHeight(): string {\n return this['max-height']?.trim() || 'none'\n }\n\n private get _wrapperStyleValue(): string {\n const overflowY = this['max-height']?.trim() ? 'auto' : 'visible'\n\n return [\n `--qxs-editor-min-height: ${this._resolvedMinHeight}`,\n `--qxs-editor-max-height: ${this._resolvedMaxHeight}`,\n `--qxs-editor-overflow-y: ${overflowY}`,\n ].join('; ')\n }\n\n private get _resolvedPlaceholder(): string {\n if (\n this.placeholder\n && this.placeholder !== DEFAULT_HEADER_PLACEHOLDER\n && this.placeholder !== DEFAULT_SLASH_PLACEHOLDER\n ) {\n return this.placeholder\n }\n return this._toolbarModeValue === 'header'\n ? DEFAULT_HEADER_PLACEHOLDER\n : DEFAULT_SLASH_PLACEHOLDER\n }\n\n private get _toolbarItemsValue(): EditorToolbarItem[] {\n if (Array.isArray(this.toolbar)) {\n return parseEditorToolbarItems(this.toolbar)\n }\n\n if (typeof this.toolbar === 'string' && this.toolbar.trim()) {\n return parseEditorToolbarItems(this.toolbar)\n }\n\n if (this._toolbarPresetValue === 'simple') {\n return [...SIMPLE_EDITOR_TOOLBAR]\n }\n\n if (this._toolbarPresetValue === 'none') {\n return []\n }\n\n return [...DEFAULT_EDITOR_TOOLBAR]\n }\n\n private _hasToolbarItem(item: EditorToolbarItem): boolean {\n return this._toolbarItemsValue.includes(item)\n }\n\n private get _headerToolbarLabelsValue(): QxsBlocksuiteEditorHeaderToolbarLabels {\n const source = this['header-toolbar-labels']\n if (!source) {\n return {}\n }\n\n let parsed: unknown = source\n if (typeof source === 'string') {\n try {\n parsed = JSON.parse(source)\n }\n catch (error) {\n console.warn('[qxs-blocksuite-editor] header-toolbar-labels parse failed, fallback to empty map', error)\n return {}\n }\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return {}\n }\n\n const labels: QxsBlocksuiteEditorHeaderToolbarLabels = {}\n for (const [key, value] of Object.entries(parsed)) {\n if (\n HEADER_TOOLBAR_LABEL_KEYS.has(key as QxsBlocksuiteEditorHeaderToolbarLabelKey)\n && typeof value === 'string'\n && value.trim()\n ) {\n labels[key as QxsBlocksuiteEditorHeaderToolbarLabelKey] = value.trim()\n }\n }\n\n return labels\n }\n\n private _getHeaderToolbarLabel(key: QxsBlocksuiteEditorHeaderToolbarLabelKey): string {\n if (this._toolbarModeValue !== 'header') {\n return ''\n }\n\n return this._headerToolbarLabelsValue[key] || ''\n }\n\n private _renderToolbarButton(\n key: QxsBlocksuiteEditorHeaderToolbarLabelKey,\n options: {\n title: string\n icon: unknown\n active?: boolean\n danger?: boolean\n onClick: (event: MouseEvent) => void\n },\n ) {\n const label = this._getHeaderToolbarLabel(key)\n const className = [\n 'bubble-btn',\n options.active ? 'is-active' : '',\n options.danger ? 'danger' : '',\n label ? 'has-label' : '',\n ]\n .filter(Boolean)\n .join(' ')\n\n return html`\n <button class=${className} @click=${options.onClick} title=${options.title}>\n ${options.icon}\n ${label ? html`<span class=\"bubble-btn__label\">${label}</span>` : null}\n </button>\n `\n }\n\n private _transformIncomingContent(value: string | null | undefined): string {\n const source = value || ''\n const transform = this['deserialize-content']\n\n if (!transform) {\n return transformIncomingContentByFormat(source, this._contentFormatValue)\n }\n\n try {\n return transform(source) || EMPTY_EDITOR_HTML\n }\n catch (error) {\n console.warn('[qxs-blocksuite-editor] deserialize-content failed, fallback to raw content', error)\n return transformIncomingContentByFormat(source, this._contentFormatValue)\n }\n }\n\n private _transformOutgoingContent(value: string): string {\n const transform = this['serialize-content']\n\n if (!transform) {\n return transformOutgoingContentByFormat(value, this._contentFormatValue)\n }\n\n try {\n return transform(value)\n }\n catch (error) {\n console.warn('[qxs-blocksuite-editor] serialize-content failed, fallback to raw html', error)\n return transformOutgoingContentByFormat(value, this._contentFormatValue)\n }\n }\n\n private _getEditorCharacterCount(): number {\n return this._editor?.getText().length ?? 0\n }\n\n @property({ type: Object, attribute: 'upload-image' })\n 'upload-image': ImageUploadHandler = async (file: File) => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = e => resolve(e.target?.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n }\n\n @state() private _editor: Editor | null = null\n private _pendingContent: string | null = null\n private _tableRows = 3\n private _tableCols = 3\n @state() private _hoverRow = 0\n @state() private _hoverCol = 0\n @state() private _tableDropdownOpen = false\n @state() private _tableCellToolbar: { x: number, y: number, visible: boolean, cellRow: number, cellCol: number } = { x: 0, y: 0, visible: false, cellRow: 0, cellCol: 0 }\n @state() private _imageToolbar: { x: number, y: number, visible: boolean } = { x: 0, y: 0, visible: false }\n @state() private _linkEditor = { x: 0, y: 0, visible: false, url: '', label: '' }\n @state() private _isEditorFocused = false\n @state() private _selectedImage: { pos: number, width: number, align: string } | null = null\n private _hasSlashCommand = false\n private _slashCommandRange: { from: number, to: number } | null = null\n private _slashInlineMarkState: { type: SlashInlineMark, lineStart: number, startPos: number } | null = null\n private _isComposingText = false\n private _isUpdating = false\n private _pendingImageInsertPos: number | null = null\n private _linkSelection: { from: number, to: number } | null = null\n private _preserveFocusOnInternalClick = false\n\n private _initEditor() {\n if (this._editor) { return }\n\n const el = this.shadowRoot?.querySelector<HTMLElement>('.editor-content')\n if (!el) {\n requestAnimationFrame(() => this._initEditor())\n return\n }\n\n while (el.firstChild) {\n el.removeChild(el.firstChild)\n }\n\n const useModel = this._useModelValue\n const modelValue = this.getAttribute('model-value') ?? this['model-value']\n const contentValue = this.content\n\n const initialContent = useModel\n ? this._transformIncomingContent(this._pendingContent ?? modelValue)\n : this._transformIncomingContent(this._pendingContent ?? contentValue)\n\n const extensions: any[] = [\n Document,\n Paragraph,\n Text,\n Bold,\n Italic,\n Underline,\n Strike,\n Code,\n Heading.configure({ levels: [1, 2, 3] }),\n BulletList,\n OrderedList,\n TaskList,\n TaskItem,\n ListItem,\n Blockquote,\n HorizontalRule,\n History,\n ExtendedImage.configure({\n inline: false,\n allowBase64: true,\n }),\n Link.extend({\n inclusive: false,\n }).configure({\n openOnClick: false,\n HTMLAttributes: {\n rel: 'noopener noreferrer',\n },\n }),\n TextAlign.configure({\n types: ['heading', 'paragraph'],\n }),\n Table.configure({\n resizable: true,\n }),\n TableRow,\n TableCell,\n TableHeader,\n Placeholder.configure({\n placeholder: this._resolvedPlaceholder,\n }),\n ]\n\n this._editor = new Editor({\n element: el,\n extensions,\n editable: this._isEditable,\n content: initialContent,\n })\n\n this._editor.view.dom.addEventListener('compositionstart', this._handleCompositionStart)\n this._editor.view.dom.addEventListener('compositionend', this._handleCompositionEnd)\n\n this._pendingContent = null\n\n this._editor.on('selectionUpdate', () => {\n this._syncSlashInlineMarkState()\n this._restoreSlashInlineMarkIfNeeded()\n if (this._toolbarModeValue === 'slash') {\n this._updateBubbleMenuPosition()\n }\n if (this._editor?.isActive('table')) {\n this._showTableCellToolbar()\n }\n else {\n this._hideTableCellToolbar()\n }\n this._syncImageSelectionState()\n })\n\n this._editor.on('transaction', () => {\n if (this._editor?.isActive('table')) {\n this._showTableCellToolbar()\n }\n else {\n this._hideTableCellToolbar()\n }\n this._checkSlashCommand()\n this._syncSlashInlineMarkState()\n this._restoreSlashInlineMarkIfNeeded()\n this._setupTableEdgeDetection()\n this._syncImageSelectionState()\n })\n\n this._editor.on('update', () => {\n this._emitContentChange()\n })\n }\n\n private _tableEdgeDetectionSetup = false\n\n private _toggleTaskItemChecked(event: Event) {\n const target = event.target\n const editor = this._editor\n if (!(target instanceof HTMLInputElement) || target.type !== 'checkbox' || !editor) {\n return\n }\n\n const taskItem = target.closest('li[data-type=\"taskItem\"]')\n if (!taskItem) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n const basePos = editor.view.posAtDOM(taskItem, 0)\n const searchFrom = Math.max(0, basePos - 2)\n const searchTo = Math.min(editor.state.doc.content.size, basePos + 2)\n\n let taskItemPos: number | null = null\n editor.state.doc.nodesBetween(searchFrom, searchTo, (node, pos) => {\n if (node.type.name === 'taskItem') {\n taskItemPos = pos\n return false\n }\n return undefined\n })\n\n if (taskItemPos === null) {\n return\n }\n\n const node = editor.state.doc.nodeAt(taskItemPos)\n if (!node || node.type.name !== 'taskItem') {\n return\n }\n\n editor.view.dispatch(editor.state.tr.setNodeMarkup(taskItemPos, undefined, {\n ...node.attrs,\n checked: !node.attrs.checked,\n }))\n }\n\n private _emitContentChange() {\n if (!this._editor) { return }\n const snapshot = this.getContentSnapshot()\n\n if (this._showCharacterCountValue) {\n this.requestUpdate()\n }\n\n this.dispatchEvent(new CustomEvent<QxsBlocksuiteEditorContentSnapshot>('content-update', {\n detail: snapshot,\n bubbles: true,\n composed: true,\n }))\n\n this.dispatchEvent(new CustomEvent('content-change', {\n detail: snapshot.value,\n bubbles: true,\n composed: true,\n }))\n }\n\n private _setupTableEdgeDetection() {\n const editorContent = this.shadowRoot?.querySelector('.editor-content')\n const editorWrapper = this.shadowRoot?.querySelector('.editor-wrapper')\n if (!editorContent || this._tableEdgeDetectionSetup) { return }\n\n this._tableEdgeDetectionSetup = true\n\n const handleEditorClick = (event: Event) => {\n this._toggleTaskItemChecked(event)\n\n const target = event.target\n if (\n target instanceof Element\n && target.closest('.editor-header, .bubble-menu, .table-cell-toolbar, .image-toolbar, .link-editor')\n ) {\n return\n }\n if (!this._isEditable) {\n return\n }\n this._editor?.chain().focus().run()\n }\n\n editorContent.addEventListener('click', handleEditorClick as EventListener)\n editorWrapper?.addEventListener('click', handleEditorClick as EventListener)\n }\n\n private _handleWrapperFocusIn() {\n this._preserveFocusOnInternalClick = false\n this._isEditorFocused = true\n }\n\n private _handleHeaderToolbarMouseDown(event: MouseEvent) {\n if (!this._isEditable) {\n return\n }\n\n const target = event.target\n if (!(target instanceof Element) || !target.closest('button, .bubble-dropdown, .table-cell')) {\n return\n }\n\n // Keep the ProseMirror selection alive while using the header toolbar.\n event.preventDefault()\n this._preserveFocusOnInternalClick = true\n requestAnimationFrame(() => {\n this._preserveFocusOnInternalClick = false\n })\n }\n\n private _handleWrapperMouseDown(event: MouseEvent) {\n const target = event.target\n if (\n !this._isEditable\n || !(target instanceof Element)\n || target.closest('.editor-header, .bubble-menu, .table-cell-toolbar, .image-toolbar, .link-editor')\n ) {\n return\n }\n\n this._preserveFocusOnInternalClick = true\n requestAnimationFrame(() => {\n this._preserveFocusOnInternalClick = false\n })\n }\n\n private _handleWrapperFocusOut(event: FocusEvent) {\n const nextTarget = event.relatedTarget as Node | null\n const wrapper = this.shadowRoot?.querySelector('.editor-wrapper')\n if (this._preserveFocusOnInternalClick) {\n return\n }\n if (nextTarget && wrapper?.contains(nextTarget)) {\n return\n }\n this._isEditorFocused = false\n this._tableDropdownOpen = false\n this._closeLinkEditor()\n }\n\n private _isHeaderVisible(): boolean {\n return this._toolbarModeValue === 'header'\n && !this._previewValue\n && (\n this._headerAlwaysVisibleValue\n || this._isEditorFocused\n || this._tableDropdownOpen\n || Boolean(this._selectedImage)\n )\n }\n\n private _getImageSelection() {\n const editor = this._editor\n const selection: any = editor?.state.selection\n if (!editor || !selection?.node || selection.node.type?.name !== 'image') {\n return null\n }\n\n return {\n pos: selection.from,\n attrs: selection.node.attrs ?? {},\n }\n }\n\n private _getImageMaxWidth() {\n const editorContent = this.shadowRoot?.querySelector<HTMLElement>('.editor-content')\n const availableWidth = (editorContent?.clientWidth ?? DEFAULT_IMAGE_WIDTH) - 32\n return Math.max(MIN_IMAGE_WIDTH, Math.min(DEFAULT_IMAGE_WIDTH, availableWidth))\n }\n\n private async _getImageNaturalWidth(file: File) {\n return await new Promise<number | null>((resolve) => {\n const objectUrl = URL.createObjectURL(file)\n const image = new window.Image()\n\n image.onload = () => {\n const naturalWidth = image.naturalWidth\n URL.revokeObjectURL(objectUrl)\n resolve(Number.isFinite(naturalWidth) && naturalWidth > 0 ? naturalWidth : null)\n }\n\n image.onerror = () => {\n URL.revokeObjectURL(objectUrl)\n resolve(null)\n }\n\n image.src = objectUrl\n })\n }\n\n private _syncImageSelectionState() {\n const selection = this._getImageSelection()\n if (!selection) {\n this._selectedImage = null\n if (this._toolbarModeValue === 'slash') {\n this._hideImageToolbar()\n }\n return\n }\n\n const width = Number(selection.attrs.width)\n const align = String(selection.attrs.align || 'left')\n this._selectedImage = {\n pos: selection.pos,\n width: Number.isFinite(width) && width > 0 ? width : this._getImageMaxWidth(),\n align,\n }\n\n if (this._toolbarModeValue !== 'slash') {\n this._hideImageToolbar()\n return\n }\n\n const editor = this._editor\n const wrapperRect = this.shadowRoot?.querySelector('.editor-wrapper')?.getBoundingClientRect()\n if (!editor || !wrapperRect) { return }\n const coords = editor.view.coordsAtPos(selection.pos)\n const x = coords.left - wrapperRect.left + (coords.right - coords.left) / 2\n const y = coords.top - wrapperRect.top - 40\n this._showImageToolbar({ x, y })\n }\n\n private _clearSlashCommandText() {\n if (!this._editor || !this._slashCommandRange) { return }\n const { from, to } = this._slashCommandRange\n this._editor.chain().focus().deleteRange({ from, to }).run()\n this._hasSlashCommand = false\n this._slashCommandRange = null\n }\n\n private _checkSlashCommand() {\n if (!this._editor) { return }\n const { selection } = this._editor.state\n if (!selection.empty) {\n this._hasSlashCommand = false\n this._slashCommandRange = null\n return\n }\n\n const { $from } = selection as any\n const textBefore = $from.parent.textBetween(0, $from.parentOffset, ' ', ' ')\n const matched = /(?:^|\\s)(\\/\\S*)$/.exec(textBefore)\n\n if (!matched) {\n this._hasSlashCommand = false\n this._slashCommandRange = null\n return\n }\n\n const slashText = matched[1]\n this._hasSlashCommand = true\n this._slashCommandRange = {\n from: selection.from - slashText.length,\n to: selection.from,\n }\n }\n\n firstUpdated() {\n this._injectCustomStyles()\n queueMicrotask(() => {\n if (this.isConnected) {\n this._initEditor()\n }\n })\n }\n\n updated(changed: Map<string, unknown>) {\n if (changed.has('custom-styles')) {\n this._injectCustomStyles()\n }\n\n if (this._editor) {\n if (\n changed.has('content')\n || (changed.has('model-value') && this._useModelValue)\n || changed.has('deserialize-content')\n || changed.has('content-format')\n ) {\n const newContent = this._transformIncomingContent(this._useModelValue ? this['model-value'] : this.content)\n if (newContent !== this._editor.getHTML()) {\n this._editor.commands.setContent(newContent)\n }\n }\n if (changed.has('readonly') || changed.has('preview') || changed.has('editable')) {\n this._editor.setEditable(this._isEditable)\n }\n return\n }\n\n // 编辑器未初始化时,只保存待处理内容,不重复初始化\n if (changed.has('content')) {\n this._pendingContent = this.content\n }\n\n if (changed.has('model-value') && this._useModelValue) {\n this._pendingContent = this['model-value']\n }\n\n // 只有在 firstUpdated 时才会初始化编辑器\n // 这里不再重复调用 _initEditor()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n const editorDom = this._editor?.view?.dom\n editorDom?.removeEventListener('compositionstart', this._handleCompositionStart)\n editorDom?.removeEventListener('compositionend', this._handleCompositionEnd)\n this._editor?.destroy()\n this._editor = null\n }\n\n getContent(): string {\n return this.getContentSnapshot().value\n }\n\n getContentSnapshot(): QxsBlocksuiteEditorContentSnapshot {\n const html = this._editor?.getHTML() ?? ''\n const text = this._editor?.getText().trim() ?? ''\n\n return {\n value: html ? this._transformOutgoingContent(html) : '',\n html,\n text,\n format: this._contentFormatValue,\n }\n }\n\n forceUpdate(): void {\n this.requestUpdate()\n if (this._editor) {\n const newContent = this._transformIncomingContent(this._useModelValue ? this['model-value'] : this.content)\n if (newContent !== this._editor.getHTML()) {\n this._editor.commands.setContent(newContent)\n }\n }\n }\n\n private _applyFormat(command: () => void) {\n this._clearSlashCommandText()\n this._clearSlashInlineMarkState(true)\n command()\n }\n\n private _getCurrentLineStart(editor: Editor) {\n const { selection } = editor.state\n if (!selection.empty) { return null }\n return selection.$from.start()\n }\n\n private _handleCompositionStart = () => {\n this._isComposingText = true\n }\n\n private _handleCompositionEnd = () => {\n this._isComposingText = false\n requestAnimationFrame(() => {\n this._syncSlashInlineMarkState()\n this._restoreSlashInlineMarkIfNeeded()\n })\n }\n\n private _getSlashCommandContext() {\n const editor = this._editor\n const range = this._slashCommandRange\n if (!editor || !range) { return null }\n\n const $from = editor.state.doc.resolve(range.from)\n return {\n lineFrom: $from.start(),\n lineTo: range.from,\n }\n }\n\n private _clearSlashInlineMarkState(force = false) {\n const editor = this._editor\n const state = this._slashInlineMarkState\n if (!editor || !state) { return }\n\n const { selection } = editor.state\n const currentLineStart = this._getCurrentLineStart(editor)\n if (!force && currentLineStart === state.lineStart && selection.empty && selection.to >= state.startPos) {\n return\n }\n\n this._slashInlineMarkState = null\n\n const pos = editor.state.selection.to\n let chain = editor.chain().focus().setTextSelection({ from: pos, to: pos })\n\n switch (state.type) {\n case 'bold':\n chain = chain.unsetBold()\n break\n case 'italic':\n chain = chain.unsetItalic()\n break\n case 'underline':\n chain = chain.unsetUnderline()\n break\n case 'strike':\n chain = chain.unsetStrike()\n break\n case 'code':\n chain = chain.unsetCode()\n break\n }\n\n chain.run()\n }\n\n private _runInlineMarkAction(\n type: SlashInlineMark,\n chain: ReturnType<Editor['chain']>,\n mode: 'set' | 'unset',\n ) {\n switch (type) {\n case 'bold':\n return mode === 'set' ? chain.setBold() : chain.unsetBold()\n case 'italic':\n return mode === 'set' ? chain.setItalic() : chain.unsetItalic()\n case 'underline':\n return mode === 'set' ? chain.setUnderline() : chain.unsetUnderline()\n case 'strike':\n return mode === 'set' ? chain.setStrike() : chain.unsetStrike()\n case 'code':\n return mode === 'set' ? chain.setCode() : chain.unsetCode()\n }\n }\n\n private _syncSlashInlineMarkState() {\n if (!this._slashInlineMarkState || !this._editor) { return }\n if (this._isComposingText) { return }\n if (this._shouldEndSlashInlineMarkAtCursor()) {\n this._clearSlashInlineMarkState(true)\n return\n }\n this._clearSlashInlineMarkState()\n }\n\n private _shouldEndSlashInlineMarkAtCursor() {\n const editor = this._editor\n const state = this._slashInlineMarkState\n if (!editor || !state) { return false }\n\n const { selection } = editor.state\n const currentLineStart = this._getCurrentLineStart(editor)\n if (!selection.empty || currentLineStart !== state.lineStart || selection.to <= state.startPos) {\n return false\n }\n\n const charBefore = editor.state.doc.textBetween(selection.to - 1, selection.to, '\\n', '\\n')\n return /\\s/.test(charBefore)\n }\n\n private _hasInlineMarkAtCursor(type: SlashInlineMark) {\n const editor = this._editor\n if (!editor) { return false }\n\n const markType = editor.schema.marks[type]\n if (!markType) { return false }\n\n const { selection, storedMarks } = editor.state\n if (!selection.empty) { return false }\n\n const marks = storedMarks ?? selection.$from.marks()\n return marks.some(mark => mark.type === markType)\n }\n\n private _restoreSlashInlineMarkIfNeeded() {\n const editor = this._editor\n const state = this._slashInlineMarkState\n if (!editor || !state) { return }\n\n const { selection } = editor.state\n const currentLineStart = this._getCurrentLineStart(editor)\n if (!selection.empty || currentLineStart !== state.lineStart || selection.to < state.startPos) { return }\n if (this._hasInlineMarkAtCursor(state.type)) { return }\n\n const pos = editor.state.selection.to\n this._runInlineMarkAction(\n state.type,\n editor.chain().focus().setTextSelection({ from: pos, to: pos }),\n 'set',\n ).run()\n }\n\n private _setInlineMarkState(type: SlashInlineMark, startPos: number) {\n const lineStart = this._getCurrentLineStart(this._editor!)\n this._slashInlineMarkState = lineStart === null ? null : { type, lineStart, startPos }\n }\n\n private _applyInlineMarkToCurrentLine(type: SlashInlineMark, mode: 'set' | 'unset') {\n const editor = this._editor\n if (!editor) { return false }\n\n const { selection } = editor.state\n if (!selection.empty) {\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection({ from: selection.from, to: selection.to }),\n mode,\n ).run()\n if (mode === 'unset') {\n this._clearSlashInlineMarkState(true)\n }\n return true\n }\n\n const cursorPos = selection.from\n const $from = editor.state.doc.resolve(cursorPos)\n const lineRange = { from: $from.start(), to: $from.end() }\n\n this._clearSlashInlineMarkState(true)\n\n if (lineRange.from < lineRange.to) {\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection(lineRange),\n mode,\n ).run()\n }\n\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection({ from: cursorPos, to: cursorPos }),\n mode,\n ).run()\n\n if (mode === 'set') {\n this._setInlineMarkState(type, cursorPos)\n }\n\n return true\n }\n\n private _toggleToolbarInlineMark(type: SlashInlineMark) {\n return this._applyInlineMarkToCurrentLine(\n type,\n this._hasInlineMarkAtCursor(type) ? 'unset' : 'set',\n )\n }\n\n private _applySlashInlineMark(\n type: SlashInlineMark,\n ) {\n const editor = this._editor\n const context = this._getSlashCommandContext()\n if (!editor || !context) { return false }\n\n this._clearSlashCommandText()\n this._clearSlashInlineMarkState(true)\n\n const cursorPos = editor.state.selection.to\n const lineRange = {\n from: context.lineFrom,\n to: editor.state.doc.resolve(cursorPos).end(),\n }\n\n if (lineRange.from < lineRange.to) {\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection(lineRange),\n 'set',\n ).run()\n }\n\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection({ from: cursorPos, to: cursorPos }),\n 'set',\n ).run()\n\n this._setInlineMarkState(type, cursorPos)\n return true\n }\n\n private _applySlashLineBlock(\n applyBlock: (chain: ReturnType<Editor['chain']>) => ReturnType<Editor['chain']>,\n ) {\n const editor = this._editor\n const context = this._getSlashCommandContext()\n if (!editor || !context) { return false }\n\n this._clearSlashCommandText()\n applyBlock(\n editor.chain().focus().setTextSelection({ from: context.lineFrom, to: context.lineTo }),\n ).run()\n return true\n }\n\n private _toggleBold() {\n if (this._applySlashInlineMark('bold')) {\n return\n }\n this._toggleToolbarInlineMark('bold')\n }\n\n private _toggleItalic() {\n if (this._applySlashInlineMark('italic')) {\n return\n }\n this._toggleToolbarInlineMark('italic')\n }\n\n private _toggleUnderline() {\n if (this._applySlashInlineMark('underline')) {\n return\n }\n this._toggleToolbarInlineMark('underline')\n }\n\n private _toggleStrike() {\n if (this._applySlashInlineMark('strike')) {\n return\n }\n this._toggleToolbarInlineMark('strike')\n }\n\n private _toggleCode() {\n if (this._applySlashInlineMark('code')) {\n return\n }\n this._toggleToolbarInlineMark('code')\n }\n\n private _setHeading(level: number) {\n if (this._applySlashLineBlock(chain => chain.setHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }))) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }).run())\n }\n\n private _setParagraph() {\n if (this._applySlashLineBlock(chain => chain.setParagraph())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().setParagraph().run())\n }\n\n private _toggleBulletList() {\n if (this._applySlashLineBlock(chain => chain.toggleBulletList())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleBulletList().run())\n }\n\n private _toggleOrderedList() {\n if (this._applySlashLineBlock(chain => chain.toggleOrderedList())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleOrderedList().run())\n }\n\n private _toggleTaskList() {\n if (this._applySlashLineBlock(chain => chain.toggleTaskList())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleTaskList().run())\n }\n\n private _toggleBlockquote() {\n if (this._applySlashLineBlock(chain => chain.toggleBlockquote())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleBlockquote().run())\n }\n\n private _setTextAlign(align: string) {\n if (this._applySlashLineBlock(chain => chain.setTextAlign(align as any))) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().setTextAlign(align as any).run())\n }\n\n private _normalizeLinkUrl(url: string) {\n const trimmed = url.trim()\n if (!trimmed) { return '' }\n if (/^(https?:\\/\\/|mailto:|tel:|#|\\/)/i.test(trimmed)) {\n return trimmed\n }\n return `https://${trimmed}`\n }\n\n private _getLinkLabelFromRange(range: { from: number, to: number } | null) {\n const editor = this._editor\n if (!editor || !range || range.from >= range.to) {\n return ''\n }\n return editor.state.doc.textBetween(range.from, range.to, '')\n }\n\n private _getLinkTargetRange() {\n const editor = this._editor\n if (!editor) { return null }\n\n const { selection } = editor.state\n if (!selection.empty) {\n return { from: selection.from, to: selection.to }\n }\n\n if (editor.isActive('link')) {\n editor.chain().focus().extendMarkRange('link').run()\n return {\n from: editor.state.selection.from,\n to: editor.state.selection.to,\n }\n }\n\n const $from = editor.state.doc.resolve(selection.from)\n return {\n from: $from.start(),\n to: $from.end(),\n }\n }\n\n private _setLink(event: MouseEvent) {\n const editor = this._editor\n const wrapper = this.shadowRoot?.querySelector<HTMLElement>('.editor-wrapper')\n const trigger = event.currentTarget instanceof HTMLElement ? event.currentTarget : null\n if (!editor || !wrapper || !trigger) { return }\n\n const linkRange = this._getLinkTargetRange()\n this._linkSelection = linkRange\n\n const wrapperRect = wrapper.getBoundingClientRect()\n const triggerRect = trigger.getBoundingClientRect()\n const maxLeft = Math.max(12, wrapperRect.width - 332)\n const left = Math.min(Math.max(12, triggerRect.left - wrapperRect.left), maxLeft)\n const top = triggerRect.bottom - wrapperRect.top + 8\n const currentHref = String(editor.getAttributes('link').href || '')\n const currentLabel = this._getLinkLabelFromRange(linkRange)\n\n this._linkEditor = {\n x: left,\n y: top,\n visible: true,\n url: currentHref,\n label: currentLabel,\n }\n\n this.updateComplete.then(() => {\n const input = this.shadowRoot?.querySelector<HTMLInputElement>('.link-editor__input[data-field=\"url\"]')\n input?.focus()\n input?.select()\n })\n }\n\n private _closeLinkEditor() {\n this._linkEditor = { ...this._linkEditor, visible: false }\n }\n\n private _handleLinkEditorInput(event: Event) {\n const target = event.target as HTMLInputElement\n const field = target.dataset.field === 'label' ? 'label' : 'url'\n this._linkEditor = {\n ...this._linkEditor,\n [field]: target.value,\n }\n }\n\n private _applyLink() {\n const editor = this._editor\n const href = this._normalizeLinkUrl(this._linkEditor.url)\n const label = this._linkEditor.label.trim() || href\n if (!editor || !href) { return }\n\n this._clearSlashCommandText()\n\n const selection = this._linkSelection ?? this._getLinkTargetRange() ?? editor.state.selection\n const insertTo = selection.from + label.length\n\n editor\n .chain()\n .focus()\n .insertContentAt(\n { from: selection.from, to: selection.to },\n {\n type: 'text',\n text: label,\n marks: [{ type: 'link', attrs: { href } }],\n },\n )\n .setTextSelection({ from: insertTo, to: insertTo })\n .run()\n\n this._closeLinkEditor()\n }\n\n private _removeLink() {\n const editor = this._editor\n if (!editor) { return }\n\n const selection = this._linkSelection ?? editor.state.selection\n let chain = editor.chain().focus()\n if (selection.from !== selection.to) {\n chain = chain.setTextSelection(selection)\n }\n chain.extendMarkRange('link').unsetLink().run()\n this._closeLinkEditor()\n }\n\n private _handleLinkEditorKeydown(event: KeyboardEvent) {\n if (event.key === 'Enter') {\n event.preventDefault()\n this._applyLink()\n return\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n this._closeLinkEditor()\n }\n }\n\n private _insertTable(rows?: number, cols?: number) {\n this._editor?.chain().focus().insertTable({ rows: rows ?? this._tableRows, cols: cols ?? this._tableCols, withHeaderRow: true }).run()\n }\n\n private async _handleImageUpload(e: Event) {\n const input = e.target as HTMLInputElement\n const file = input.files?.[0]\n if (file) {\n try {\n const naturalWidth = await this._getImageNaturalWidth(file)\n const src = await this['upload-image'](file)\n const initialWidth = naturalWidth\n ? Math.min(naturalWidth, this._getImageMaxWidth())\n : this._getImageMaxWidth()\n\n this._clearSlashCommandText()\n const pendingInsertPos = this._pendingImageInsertPos\n this._pendingImageInsertPos = null\n\n if (pendingInsertPos !== null) {\n this._insertImageAt(pendingInsertPos, {\n src,\n width: initialWidth,\n align: 'left',\n })\n }\n else {\n this._editor?.chain().focus().setImage({\n src,\n width: initialWidth,\n align: 'left',\n } as any).run()\n }\n }\n catch (err) {\n console.error('图片上传失败:', err)\n const error = err instanceof Error ? err : new Error('图片上传失败')\n this.dispatchEvent(new CustomEvent<QxsBlocksuiteEditorImageUploadErrorDetail>('image-upload-error', {\n detail: {\n file,\n error,\n },\n bubbles: true,\n composed: true,\n }))\n }\n }\n input.value = ''\n }\n\n private _triggerImageUpload() {\n this._clearSlashCommandText()\n const input = this.shadowRoot?.querySelector<HTMLInputElement>('.image-input')\n input?.click()\n }\n\n private _insertTableByClick(rows: number, cols: number) {\n this._clearSlashCommandText()\n this._tableRows = rows\n this._tableCols = cols\n this._insertTable(rows, cols)\n }\n\n private _showTableCellToolbar() {\n if (!this._editor?.isActive('table')) { return }\n const { state } = this._editor\n const { selection } = state\n const coords = this._editor.view.coordsAtPos(selection.from)\n const editorWrapper = this.shadowRoot?.querySelector<HTMLElement>('.editor-wrapper')\n if (!editorWrapper) { return }\n const wrapperRect = editorWrapper.getBoundingClientRect()\n\n const cellRow = this._getTableCellRow()\n const cellCol = this._getTableCellCol()\n const isTopRow = cellRow === 0\n const isLeftCol = cellCol === 0\n\n // Only show toolbar on top row or left column\n if (!isTopRow && !isLeftCol) { return }\n\n requestAnimationFrame(() => {\n this._tableCellToolbar = {\n x: coords.left - wrapperRect.left,\n y: coords.bottom - wrapperRect.top + 8,\n visible: true,\n cellRow,\n cellCol,\n }\n })\n }\n\n private _getTableCellRow(): number {\n if (!this._editor) { return 0 }\n const { selection } = this._editor.state\n const $pos = this._editor.state.doc.resolve(selection.from)\n for (let d = $pos.depth; d > 0; d--) {\n const node = $pos.node(d)\n if (node.type.name === 'tableCell') {\n return $pos.index(d - 1)\n }\n }\n return 0\n }\n\n private _getTableCellCol(): number {\n if (!this._editor) { return 0 }\n const { selection } = this._editor.state\n const $pos = this._editor.state.doc.resolve(selection.from)\n for (let d = $pos.depth; d > 0; d--) {\n const node = $pos.node(d)\n if (node.type.name === 'tableCell') {\n return $pos.index(d)\n }\n }\n return 0\n }\n\n private _hideTableCellToolbar() {\n requestAnimationFrame(() => {\n this._tableCellToolbar = { ...this._tableCellToolbar, visible: false }\n })\n }\n\n private _addTableRowAbove() {\n this._editor?.chain().focus().addRowBefore().run()\n this._hideTableCellToolbar()\n }\n\n private _addTableRowBelow() {\n this._editor?.chain().focus().addRowAfter().run()\n this._hideTableCellToolbar()\n }\n\n private _addTableColumnLeft() {\n this._editor?.chain().focus().addColumnBefore().run()\n this._hideTableCellToolbar()\n }\n\n private _addTableColumnRight() {\n this._editor?.chain().focus().addColumnAfter().run()\n this._hideTableCellToolbar()\n }\n\n private _deleteTableRow() {\n this._editor?.chain().focus().deleteRow().run()\n this._hideTableCellToolbar()\n }\n\n private _deleteTableColumn() {\n this._editor?.chain().focus().deleteColumn().run()\n this._hideTableCellToolbar()\n }\n\n private _deleteTable() {\n this._editor?.chain().focus().deleteTable().run()\n this._hideTableCellToolbar()\n }\n\n // Image Toolbar Methods\n private _showImageToolbar(pos: { x: number, y: number }) {\n requestAnimationFrame(() => {\n this._imageToolbar = { x: pos.x, y: pos.y, visible: true }\n })\n }\n\n private _hideImageToolbar() {\n requestAnimationFrame(() => {\n this._imageToolbar = { ...this._imageToolbar, visible: false }\n })\n }\n\n private _deleteImage() {\n const selectedImage = this._getSelectedImageNode()\n if (!selectedImage) { return }\n\n const { editor, pos, node } = selectedImage\n editor.view.dispatch(editor.state.tr.delete(pos, pos + node.nodeSize))\n this._selectedImage = null\n this._pendingImageInsertPos = null\n this._hideImageToolbar()\n }\n\n private _insertImageAfter() {\n const selectedImage = this._getSelectedImageNode()\n if (!selectedImage) {\n this._triggerImageUpload()\n return\n }\n\n this._pendingImageInsertPos = selectedImage.pos + selectedImage.node.nodeSize\n this._triggerImageUpload()\n }\n\n private _getSelectedImageNode() {\n const editor = this._editor\n const pos = this._selectedImage?.pos\n if (!editor || pos === undefined) { return null }\n\n const node = editor.state.doc.nodeAt(pos)\n if (!node || node.type.name !== 'image') { return null }\n\n return { editor, pos, node }\n }\n\n private _insertImageAt(pos: number, attrs: Record<string, unknown>) {\n const editor = this._editor\n if (!editor) { return }\n\n const insertPos = Math.max(0, Math.min(pos, editor.state.doc.content.size))\n editor\n .chain()\n .insertContentAt(insertPos, { type: 'image', attrs })\n .setNodeSelection(insertPos)\n .run()\n }\n\n private _updateSelectedImageAttributes(attrs: Record<string, unknown>) {\n const selectedImage = this._getSelectedImageNode()\n if (!selectedImage) { return }\n\n const { editor, pos, node } = selectedImage\n editor.view.dispatch(editor.state.tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n ...attrs,\n }))\n }\n\n private _setImageWidth(width: number) {\n const nextWidth = Math.max(MIN_IMAGE_WIDTH, Math.min(this._getImageMaxWidth(), Math.round(width)))\n this._updateSelectedImageAttributes({ width: nextWidth })\n }\n\n private _handleImageWidthInput(e: Event) {\n const rawValue = (e.target as HTMLInputElement).value.trim()\n if (!rawValue) { return }\n\n const value = Number(rawValue)\n if (!Number.isFinite(value)) { return }\n this._setImageWidth(value)\n }\n\n private _setImageAlignLeft() {\n this._updateSelectedImageAttributes({ align: 'left' })\n }\n\n private _setImageAlignCenter() {\n this._updateSelectedImageAttributes({ align: 'center' })\n }\n\n private _setImageAlignRight() {\n this._updateSelectedImageAttributes({ align: 'right' })\n }\n\n private _getTextLabel(): string {\n const editor = this._editor\n if (!editor) { return '正文' }\n if (editor.isActive('heading', { level: 1 })) { return '标题 1' }\n if (editor.isActive('heading', { level: 2 })) { return '标题 2' }\n if (editor.isActive('heading', { level: 3 })) { return '标题 3' }\n return '正文'\n }\n\n private _getAlignLabel(): string {\n const editor = this._editor\n if (!editor) { return '对齐' }\n if (editor.isActive({ textAlign: 'center' })) { return '居中' }\n if (editor.isActive({ textAlign: 'right' })) { return '右对齐' }\n return '左对齐'\n }\n\n private _renderImageControls() {\n const selectedImage = this._selectedImage\n if (!selectedImage) { return '' }\n\n return html`\n <button class=\"bubble-btn danger\" title=\"删除图片\" @click=${this._deleteImage}>\n <svg viewBox=\"0 0 24 24\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>\n </button>\n <button class=\"bubble-btn\" title=\"添加图片\" @click=${this._insertImageAfter}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>\n </button>\n <div class=\"bubble-divider\"></div>\n <span class=\"image-control-label\">对齐</span>\n <button class=\"bubble-btn ${selectedImage.align === 'left' ? 'is-active' : ''}\" title=\"左对齐\" @click=${this._setImageAlignLeft}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"15\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"18\" y2=\"18\"/></svg>\n </button>\n <button class=\"bubble-btn ${selectedImage.align === 'center' ? 'is-active' : ''}\" title=\"居中\" @click=${this._setImageAlignCenter}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/></svg>\n </button>\n <button class=\"bubble-btn ${selectedImage.align === 'right' ? 'is-active' : ''}\" title=\"右对齐\" @click=${this._setImageAlignRight}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"6\" y1=\"18\" x2=\"21\" y2=\"18\"/></svg>\n </button>\n <div class=\"image-size-control\">\n <span class=\"image-size-label\">宽度</span>\n <input\n class=\"image-size-range\"\n type=\"number\"\n min=\"${MIN_IMAGE_WIDTH}\"\n max=\"${this._getImageMaxWidth()}\"\n .value=${String(selectedImage.width)}\n @input=${this._handleImageWidthInput}\n />\n </div>\n `\n }\n\n private _joinToolbarGroups(groups: unknown[]) {\n return groups.flatMap((group, index) => index === 0\n ? [group]\n : [html`<div class=\"bubble-divider\"></div>`, group])\n }\n\n private _renderFormatToolbarGroup(editor: Editor | null) {\n return html`\n ${this._renderToolbarButton('bold', {\n title: '加粗',\n active: editor?.isActive('bold'),\n onClick: this._toggleBold,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/></svg>`,\n })}\n ${this._renderToolbarButton('italic', {\n title: '斜体',\n active: editor?.isActive('italic'),\n onClick: this._toggleItalic,\n icon: html`<svg viewBox=\"0 0 24 24\"><line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/></svg>`,\n })}\n ${this._renderToolbarButton('underline', {\n title: '下划线',\n active: editor?.isActive('underline'),\n onClick: this._toggleUnderline,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/></svg>`,\n })}\n ${this._renderToolbarButton('strike', {\n title: '删除线',\n active: editor?.isActive('strike'),\n onClick: this._toggleStrike,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M17.3 4.9c-2.3-.6-4.4-1-6.2-.9-2.7 0-5.3.7-5.3 3.6 0 1.5 1.8 3.3 5.3 3.9h.2m8.2 3.2c.3.4.4.8.4 1.3 0 2.9-2.7 3.6-6.2 3.6-2.3 0-4.4-.3-6.2-.9M4 12h16\"/></svg>`,\n })}\n `\n }\n\n private _renderHeadingToolbarGroup(editor: Editor | null) {\n return html`\n <div class=\"bubble-dropdown\">\n <button class=\"bubble-dropdown-btn\">\n ${this._getTextLabel()}\n <svg viewBox=\"0 0 24 24\"><polyline points=\"6 9 12 15 18 9\"/></svg>\n </button>\n <div class=\"bubble-dropdown-menu\">\n <button class=\"bubble-dropdown-item ${!editor?.isActive('heading') ? 'is-active' : ''}\" @click=${this._setParagraph}>正文</button>\n <button class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 1 }) ? 'is-active' : ''}\" @click=${() => this._setHeading(1)}>标题 1</button>\n <button class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 2 }) ? 'is-active' : ''}\" @click=${() => this._setHeading(2)}>标题 2</button>\n <button class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 3 }) ? 'is-active' : ''}\" @click=${() => this._setHeading(3)}>标题 3</button>\n </div>\n </div>\n `\n }\n\n private _renderAlignToolbarGroup(editor: Editor | null) {\n return html`\n <div class=\"bubble-dropdown\">\n <button class=\"bubble-dropdown-btn\">\n ${this._getAlignLabel()}\n <svg viewBox=\"0 0 24 24\"><polyline points=\"6 9 12 15 18 9\"/></svg>\n </button>\n <div class=\"bubble-dropdown-menu\">\n <button class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'left' }) ? 'is-active' : ''}\" @click=${() => this._setTextAlign('left')}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"15\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"18\" y2=\"18\"/></svg>\n 左对齐\n </button>\n <button class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'center' }) ? 'is-active' : ''}\" @click=${() => this._setTextAlign('center')}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/></svg>\n 居中\n </button>\n <button class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'right' }) ? 'is-active' : ''}\" @click=${() => this._setTextAlign('right')}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"6\" y1=\"18\" x2=\"21\" y2=\"18\"/></svg>\n 右对齐\n </button>\n </div>\n </div>\n `\n }\n\n private _renderCodeLinkImageToolbarGroup(editor: Editor | null) {\n return html`\n ${this._hasToolbarItem('code')\n ? this._renderToolbarButton('code', {\n title: '行内代码',\n active: editor?.isActive('code'),\n onClick: this._toggleCode,\n icon: html`<svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>`,\n })\n : ''}\n ${this._hasToolbarItem('link')\n ? this._renderToolbarButton('link', {\n title: '链接',\n active: editor?.isActive('link'),\n onClick: this._setLink,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>`,\n })\n : ''}\n ${this._hasToolbarItem('image')\n ? this._renderToolbarButton('image', {\n title: '图片',\n onClick: this._triggerImageUpload,\n icon: html`<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>`,\n })\n : ''}\n `\n }\n\n private _renderCodeToolbarButton(editor: Editor | null) {\n return this._renderToolbarButton('code', {\n title: '行内代码',\n active: editor?.isActive('code'),\n onClick: this._toggleCode,\n icon: html`<svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>`,\n })\n }\n\n private _renderLinkToolbarButton(editor: Editor | null) {\n return this._renderToolbarButton('link', {\n title: '链接',\n active: editor?.isActive('link'),\n onClick: this._setLink,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>`,\n })\n }\n\n private _renderImageToolbarButton() {\n return this._renderToolbarButton('image', {\n title: '图片',\n onClick: this._triggerImageUpload,\n icon: html`<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>`,\n })\n }\n\n private _renderListToolbarGroup(editor: Editor | null) {\n return html`\n ${this._renderToolbarButton('bulletList', {\n title: '无序列表',\n active: editor?.isActive('bulletList'),\n onClick: this._toggleBulletList,\n icon: html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"9\" y1=\"6\" x2=\"20\" y2=\"6\"/>\n <line x1=\"9\" y1=\"12\" x2=\"20\" y2=\"12\"/>\n <line x1=\"9\" y1=\"18\" x2=\"20\" y2=\"18\"/>\n <circle cx=\"4\" cy=\"6\" r=\"0.5\" fill=\"currentColor\" stroke=\"none\"/>\n <circle cx=\"4\" cy=\"12\" r=\"0.5\" fill=\"currentColor\" stroke=\"none\"/>\n <circle cx=\"4\" cy=\"18\" r=\"0.5\" fill=\"currentColor\" stroke=\"none\"/>\n </svg>`,\n })}\n ${this._renderToolbarButton('orderedList', {\n title: '有序列表',\n active: editor?.isActive('orderedList'),\n onClick: this._toggleOrderedList,\n icon: html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/>\n <line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/>\n <line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/>\n <path d=\"M4 6h1v4\"/>\n <path d=\"M4 10h2\"/>\n <path d=\"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1.5\"/>\n </svg>`,\n })}\n ${this._renderToolbarButton('taskList', {\n title: '待办列表',\n active: editor?.isActive('taskList'),\n onClick: this._toggleTaskList,\n icon: html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"3\" y=\"5\" width=\"4\" height=\"4\" rx=\"1\"/>\n <polyline points=\"4 7 5 8 6.5 6.5\"/>\n <line x1=\"10\" y1=\"7\" x2=\"21\" y2=\"7\"/>\n <rect x=\"3\" y=\"15\" width=\"4\" height=\"4\" rx=\"1\"/>\n <line x1=\"10\" y1=\"17\" x2=\"21\" y2=\"17\"/>\n </svg>`,\n })}\n `\n }\n\n private _renderBlockquoteToolbarGroup(editor: Editor | null) {\n return html`\n ${this._renderToolbarButton('blockquote', {\n title: '引用',\n active: editor?.isActive('blockquote'),\n onClick: this._toggleBlockquote,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V21z\"/><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\"/></svg>`,\n })}\n `\n }\n\n private _renderTableToolbarGroup() {\n const label = this._getHeaderToolbarLabel('table')\n return html`\n <div\n class=\"bubble-dropdown ${this._tableDropdownOpen ? 'is-open' : ''}\"\n @mouseenter=${() => {\n this._tableDropdownOpen = true\n this._hoverRow = 0\n this._hoverCol = 0\n }}\n @mouseleave=${() => this._tableDropdownOpen = false}\n >\n <button class=\"bubble-dropdown-btn ${label ? 'has-label' : ''}\" title=\"表格\">\n <svg viewBox=\"0 0 24 24\" style=\"width:18px;height:18px;stroke:currentColor;stroke-width:2;fill:none;\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/></svg>\n ${label ? html`<span class=\"bubble-dropdown-btn__label\">${label}</span>` : null}\n </button>\n <div class=\"bubble-dropdown-menu\">\n <div class=\"table-grid-preview\">\n ${this._renderTableGrid()}\n </div>\n <div class=\"table-size-hint\">\n <span>${this._hoverRow > 0 ? `${this._hoverRow} × ${this._hoverCol}` : `${this._tableRows} × ${this._tableCols}`}</span>\n </div>\n </div>\n </div>\n `\n }\n\n private _getToolbarMergeKey(item: EditorToolbarItem): string {\n if (item === 'code' || item === 'link' || item === 'image') {\n return 'code-link-image'\n }\n\n return item\n }\n\n private _renderToolbarItemByKey(editor: Editor | null, item: EditorToolbarItem): unknown {\n switch (item) {\n case 'format':\n return this._renderFormatToolbarGroup(editor)\n case 'heading':\n return this._renderHeadingToolbarGroup(editor)\n case 'align':\n return this._renderAlignToolbarGroup(editor)\n case 'code':\n return this._renderCodeToolbarButton(editor)\n case 'link':\n return this._renderLinkToolbarButton(editor)\n case 'image':\n return this._renderImageToolbarButton()\n case 'list':\n return this._renderListToolbarGroup(editor)\n case 'blockquote':\n return this._renderBlockquoteToolbarGroup(editor)\n case 'table':\n return this._renderTableToolbarGroup()\n default:\n return null\n }\n }\n\n private _renderTextToolbar(editor: Editor | null) {\n const groups: unknown[] = []\n\n let currentMergeKey = ''\n let currentGroup: unknown[] = []\n\n const flushGroup = () => {\n if (currentGroup.length) {\n groups.push([...currentGroup])\n currentGroup = []\n }\n }\n\n for (const item of this._toolbarItemsValue) {\n const rendered = this._renderToolbarItemByKey(editor, item)\n if (!rendered) {\n continue\n }\n\n const mergeKey = this._getToolbarMergeKey(item)\n if (currentGroup.length && mergeKey !== currentMergeKey) {\n flushGroup()\n }\n\n currentMergeKey = mergeKey\n currentGroup.push(rendered)\n }\n\n flushGroup()\n\n return this._joinToolbarGroups(groups)\n }\n\n private _updateBubbleMenuPosition() {\n if (this._toolbarModeValue !== 'slash') { return }\n requestAnimationFrame(() => {\n const bubbleMenu = this.shadowRoot?.querySelector<HTMLElement>('.bubble-menu')\n const proseMirror = this.shadowRoot?.querySelector<HTMLElement>('.ProseMirror')\n const editorWrapper = this.shadowRoot?.querySelector<HTMLElement>('.editor-wrapper')\n if (!bubbleMenu || !proseMirror || !editorWrapper) { return }\n\n const editor = this._editor\n const isInTable = editor?.isActive('table') ?? false\n const { selection } = editor?.state ?? { selection: null }\n\n // 如果选中了表格节点(而不只是单元格内的文字),隐藏菜单\n if (isInTable && selection && !selection.empty && editor) {\n const { from, to } = selection\n const $from = editor.state.doc.resolve(from)\n const $to = editor.state.doc.resolve(to)\n // 检查选区起点和终点之间是否有表格节点\n let hasTableInSelection = false\n for (let d = $from.depth; d >= 0; d--) {\n if ($from.node(d).type.name === 'table') {\n hasTableInSelection = true\n break\n }\n }\n // 如果选区起点在表格外但终点在表格内,或者选区跨越了表格\n const fromAncestor = $from.node($from.depth)\n const toAncestor = $to.node($to.depth)\n if (fromAncestor.type.name === 'table' || toAncestor.type.name === 'table') {\n hasTableInSelection = true\n }\n if (hasTableInSelection) {\n bubbleMenu.style.opacity = '0'\n bubbleMenu.style.visibility = 'hidden'\n return\n }\n }\n\n // 如果有选中文字,显示菜单\n if (selection && !selection.empty) {\n // continue to show menu\n }\n else if (!selection || (selection.empty && !this._hasSlashCommand)) {\n bubbleMenu.style.opacity = '0'\n bubbleMenu.style.visibility = 'hidden'\n return\n }\n\n const wrapperRect = editorWrapper.getBoundingClientRect()\n const menuRect = bubbleMenu.getBoundingClientRect()\n\n const { from } = selection!\n const coords = this._editor?.view.coordsAtPos(from)\n if (!coords) { return }\n\n let left = coords.left - wrapperRect.left\n let top = coords.top - wrapperRect.top - 40\n\n if (left + menuRect.width > wrapperRect.width) {\n left = wrapperRect.width - menuRect.width - 8\n }\n if (left < 0) {\n left = 8\n }\n\n if (top < 0) {\n top = coords.bottom - wrapperRect.top + 8\n }\n\n bubbleMenu.style.left = `${left}px`\n bubbleMenu.style.top = `${top}px`\n bubbleMenu.style.opacity = '1'\n bubbleMenu.style.visibility = 'visible'\n })\n }\n\n render() {\n const editor = this._editor\n const headerTemplate = !this._previewValue && this._toolbarModeValue === 'header'\n ? html`\n <div class=\"editor-header ${this._isHeaderVisible() ? 'is-visible' : ''}\">\n <div class=\"editor-header__inner\" @mousedown=${this._handleHeaderToolbarMouseDown}>\n ${this._selectedImage\n ? this._renderImageControls()\n : this._renderTextToolbar(editor)}\n </div>\n </div>\n `\n : null\n const shouldShowCharacterCount = this._showCharacterCountValue && !this._previewValue\n\n return html`\n <div\n class=\"editor-wrapper ${!editor ? 'loading' : ''} ${this._previewValue ? 'preview' : ''} ${this._toolbarPositionValue === 'bottom' ? 'toolbar-bottom' : ''}\"\n style=${this._wrapperStyleValue}\n @mousedown=${this._handleWrapperMouseDown}\n @focusin=${this._handleWrapperFocusIn}\n @focusout=${this._handleWrapperFocusOut}\n >\n ${!editor\n ? html`\n <div class=\"loading-placeholder\">\n <div class=\"loading-spinner\"></div>\n <span>编辑器加载中...</span>\n </div>\n `\n : ''}\n <input\n type=\"file\"\n accept=\"image/*\"\n class=\"image-input\"\n @change=${this._handleImageUpload}\n />\n\n ${this._toolbarPositionValue === 'top' ? headerTemplate : null}\n\n <!-- Bubble Menu (悬浮操作栏) -->\n ${!this._previewValue && this._toolbarModeValue === 'slash'\n ? html`\n <div class=\"bubble-menu\">\n ${this._renderTextToolbar(editor)}\n </div>\n `\n : ''}\n\n <div class=\"editor-content\" data-empty-hint=${this._resolvedPlaceholder}></div>\n\n ${this._toolbarPositionValue === 'bottom' ? headerTemplate : null}\n\n ${shouldShowCharacterCount\n ? html`<div class=\"editor-footer\">${this._getEditorCharacterCount()} 字符</div>`\n : null}\n\n ${this._linkEditor.visible\n ? html`\n <div\n class=\"link-editor\"\n style=\"left: ${this._linkEditor.x}px; top: ${this._linkEditor.y}px;\"\n @mousedown=${(event: MouseEvent) => event.stopPropagation()}\n @click=${(event: MouseEvent) => event.stopPropagation()}\n >\n <div class=\"link-editor__field\">\n <span class=\"link-editor__label\">链接地址</span>\n <input\n class=\"link-editor__input\"\n data-field=\"url\"\n type=\"text\"\n placeholder=\"输入或粘贴链接\"\n .value=${this._linkEditor.url}\n @input=${this._handleLinkEditorInput}\n @keydown=${this._handleLinkEditorKeydown}\n />\n </div>\n <div class=\"link-editor__field\">\n <span class=\"link-editor__label\">链接名字</span>\n <input\n class=\"link-editor__input\"\n data-field=\"label\"\n type=\"text\"\n placeholder=\"输入展示名称\"\n .value=${this._linkEditor.label}\n @input=${this._handleLinkEditorInput}\n @keydown=${this._handleLinkEditorKeydown}\n />\n </div>\n <div class=\"link-editor__actions\">\n <button class=\"link-editor__action primary\" title=\"应用链接\" @click=${this._applyLink}>应用</button>\n <button class=\"link-editor__action\" title=\"取消链接编辑\" @click=${this._closeLinkEditor}>取消</button>\n ${(editor?.isActive('link') || this._linkEditor.url)\n ? html`<button class=\"link-editor__action danger\" title=\"移除链接\" @click=${this._removeLink}>移除</button>`\n : ''}\n </div>\n </div>\n `\n : ''}\n\n <!-- Table Cell Toolbar -->\n ${this._tableCellToolbar.visible && editor?.isActive('table')\n ? html`\n <div\n class=\"table-cell-toolbar\"\n style=\"left: ${this._tableCellToolbar.x}px; top: ${this._tableCellToolbar.y}px;\"\n @mousedown=${(e: Event) => e.preventDefault()}\n >\n ${this._tableCellToolbar.cellRow === 0\n ? html`\n <button class=\"table-cell-toolbar-btn\" title=\"上方添加行\" @click=${this._addTableRowAbove}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"7\"/><line x1=\"10\" y1=\"5\" x2=\"14\" y2=\"5\"/></svg>\n </button>\n <button class=\"table-cell-toolbar-btn\" title=\"下方添加行\" @click=${this._addTableRowBelow}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"17\"/><line x1=\"10\" y1=\"19\" x2=\"14\" y2=\"19\"/></svg>\n </button>\n <button class=\"table-cell-toolbar-btn danger\" title=\"删除行\" @click=${this._deleteTableRow}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"1\"/><line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"14\"/><line x1=\"15\" y1=\"10\" x2=\"15\" y2=\"14\"/></svg>\n </button>\n `\n : ''}\n ${this._tableCellToolbar.cellCol === 0\n ? html`\n ${this._tableCellToolbar.cellRow !== 0 ? html`<div style=\"width:1px;height:20px;background:#e3e3e3;margin:0 4px;\"></div>` : ''}\n <button class=\"table-cell-toolbar-btn\" title=\"左侧添加列\" @click=${this._addTableColumnLeft}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"8\" y=\"4\" width=\"8\" height=\"16\" rx=\"1\"/><line x1=\"3\" y1=\"12\" x2=\"7\" y2=\"12\"/><line x1=\"5\" y1=\"10\" x2=\"5\" y2=\"14\"/></svg>\n </button>\n <button class=\"table-cell-toolbar-btn\" title=\"右侧添加列\" @click=${this._addTableColumnRight}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"8\" y=\"4\" width=\"8\" height=\"16\" rx=\"1\"/><line x1=\"21\" y1=\"12\" x2=\"17\" y2=\"12\"/><line x1=\"19\" y1=\"10\" x2=\"19\" y2=\"14\"/></svg>\n </button>\n <button class=\"table-cell-toolbar-btn danger\" title=\"删除列\" @click=${this._deleteTableColumn}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"8\" y=\"4\" width=\"8\" height=\"16\" rx=\"1\"/><line x1=\"10\" y1=\"9\" x2=\"14\" y2=\"9\"/><line x1=\"10\" y1=\"15\" x2=\"14\" y2=\"15\"/></svg>\n </button>\n `\n : ''}\n ${this._tableCellToolbar.cellRow === 0 && this._tableCellToolbar.cellCol === 0\n ? html`\n <div style=\"width:1px;height:20px;background:#e3e3e3;margin:0 4px;\"></div>\n <button class=\"table-cell-toolbar-btn danger\" title=\"删除表格\" @click=${this._deleteTable}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>\n </button>\n `\n : ''}\n </div>\n `\n : ''}\n\n <!-- Image Toolbar -->\n ${this._toolbarModeValue === 'slash' && this._imageToolbar.visible\n ? html`\n <div\n class=\"image-toolbar\"\n style=\"left: ${this._imageToolbar.x}px; top: ${this._imageToolbar.y}px;\"\n @mousedown=${(e: Event) => e.preventDefault()}\n >\n ${this._renderImageControls()}\n </div>\n `\n : ''}\n </div>\n `\n }\n\n private _renderTableGrid() {\n const cells = []\n for (let i = 0; i < 100; i++) {\n const row = Math.floor(i / 10) + 1\n const col = (i % 10) + 1\n const isHighlight = this._hoverRow > 0 && row <= this._hoverRow && col <= this._hoverCol\n cells.push(html`\n <div\n class=\"table-cell ${isHighlight ? 'selected' : ''}\"\n @click=${() => {\n this._insertTableByClick(row, col)\n this._tableDropdownOpen = false\n }}\n @mouseenter=${() => {\n this._hoverRow = row\n this._hoverCol = col\n }}\n @mouseleave=${() => {\n this._hoverRow = 0\n this._hoverCol = 0\n }}\n ></div>\n `)\n }\n return cells\n }\n}\n\nexport function register() {}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qxs-blocksuite-editor': QxsBlocksuiteEditor\n }\n}\n"],"names":["DEFAULT_HEADER_PLACEHOLDER","DEFAULT_SLASH_PLACEHOLDER","DEFAULT_MIN_HEIGHT","HEADER_TOOLBAR_LABEL_KEYS","Set","TaskList","TiptapNode","create","name","group","content","defining","parseHTML","tag","renderHTML","_ref","HTMLAttributes","mergeAttributes","addCommands","toggleTaskList","_ref2","commands","toggleList","this","TaskItem","addAttributes","checked","default","element","getAttribute","String","Boolean","attributes","_ref3","contenteditable","type","addKeyboardShortcuts","Enter","editor","splitListItem","Tab","sinkListItem","Shift-Tab","liftListItem","ExtendedImage","Image","extend","parent","width","attr","value","Number","isFinite","align","_ref4","style","filter","join","options","QxsBlocksuiteEditor","LitElement","constructor","super","arguments","placeholder","toolbar","readonly","preview","editable","_injectedStyleEl","async","Promise","resolve","reject","reader","FileReader","onload","e","target","result","onerror","readAsDataURL","file","_editor","_pendingContent","_tableRows","_tableCols","_hoverRow","_hoverCol","_tableDropdownOpen","_tableCellToolbar","x","y","visible","cellRow","cellCol","_imageToolbar","_linkEditor","url","label","_isEditorFocused","_selectedImage","_hasSlashCommand","_slashCommandRange","_slashInlineMarkState","_isComposingText","_isUpdating","_pendingImageInsertPos","_linkSelection","_preserveFocusOnInternalClick","_tableEdgeDetectionSetup","_handleCompositionStart","_handleCompositionEnd","requestAnimationFrame","_syncSlashInlineMarkState","_restoreSlashInlineMarkIfNeeded","_injectCustomStyles","shadow","shadowRoot","remove","styleEl","document","createElement","textContent","appendChild","_useModelValue","hasAttribute","_readonlyValue","_previewValue","_editableValue","_isEditable","_toolbarModeValue","_headerAlwaysVisibleValue","_toolbarPositionValue","_toolbarPresetValue","_contentFormatValue","_showCharacterCountValue","_resolvedMinHeight","trim","_resolvedMaxHeight","_wrapperStyleValue","overflowY","_resolvedPlaceholder","_toolbarItemsValue","Array","isArray","parseEditorToolbarItems","SIMPLE_EDITOR_TOOLBAR","DEFAULT_EDITOR_TOOLBAR","_hasToolbarItem","item","includes","_headerToolbarLabelsValue","source","parsed","JSON","parse","error","labels","key","Object","entries","has","_getHeaderToolbarLabel","_renderToolbarButton","className","active","danger","html","onClick","title","icon","_transformIncomingContent","transform","transformIncomingContentByFormat","EMPTY_EDITOR_HTML","_transformOutgoingContent","transformOutgoingContentByFormat","_getEditorCharacterCount","getText","length","_initEditor","el","querySelector","firstChild","removeChild","useModel","modelValue","contentValue","initialContent","extensions","Document","Paragraph","Text","Bold","Italic","Underline","Strike","Code","Heading","configure","levels","BulletList","OrderedList","ListItem","Blockquote","HorizontalRule","History","inline","allowBase64","Link","inclusive","openOnClick","rel","TextAlign","types","Table","resizable","TableRow","TableCell","TableHeader","Placeholder","Editor","view","dom","addEventListener","on","_updateBubbleMenuPosition","isActive","_showTableCellToolbar","_hideTableCellToolbar","_syncImageSelectionState","_checkSlashCommand","_setupTableEdgeDetection","_emitContentChange","_toggleTaskItemChecked","event","HTMLInputElement","taskItem","closest","preventDefault","stopPropagation","basePos","posAtDOM","searchFrom","Math","max","searchTo","min","state","doc","size","taskItemPos","nodesBetween","node","pos","nodeAt","dispatch","tr","setNodeMarkup","attrs","snapshot","getContentSnapshot","requestUpdate","dispatchEvent","CustomEvent","detail","bubbles","composed","editorContent","editorWrapper","handleEditorClick","Element","chain","focus","run","_handleWrapperFocusIn","_handleHeaderToolbarMouseDown","_handleWrapperMouseDown","_handleWrapperFocusOut","nextTarget","relatedTarget","wrapper","contains","_closeLinkEditor","_isHeaderVisible","_getImageSelection","selection","from","_getImageMaxWidth","availableWidth","clientWidth","_getImageNaturalWidth","objectUrl","URL","createObjectURL","image","window","naturalWidth","revokeObjectURL","src","_hideImageToolbar","wrapperRect","getBoundingClientRect","coords","coordsAtPos","left","right","top","_showImageToolbar","_clearSlashCommandText","to","deleteRange","empty","$from","textBefore","textBetween","parentOffset","matched","exec","slashText","firstUpdated","queueMicrotask","isConnected","updated","changed","newContent","getHTML","setContent","setEditable","disconnectedCallback","editorDom","removeEventListener","destroy","getContent","text","format","forceUpdate","_applyFormat","command","_clearSlashInlineMarkState","_getCurrentLineStart","start","_getSlashCommandContext","range","lineFrom","lineTo","force","currentLineStart","lineStart","startPos","setTextSelection","unsetBold","unsetItalic","unsetUnderline","unsetStrike","unsetCode","_runInlineMarkAction","mode","setBold","setItalic","setUnderline","setStrike","setCode","_shouldEndSlashInlineMarkAtCursor","charBefore","test","_hasInlineMarkAtCursor","markType","schema","marks","storedMarks","some","mark","_setInlineMarkState","_applyInlineMarkToCurrentLine","cursorPos","lineRange","end","_toggleToolbarInlineMark","_applySlashInlineMark","context","_applySlashLineBlock","applyBlock","_toggleBold","_toggleItalic","_toggleUnderline","_toggleStrike","_toggleCode","_setHeading","level","setHeading","toggleHeading","_setParagraph","setParagraph","_toggleBulletList","toggleBulletList","_toggleOrderedList","toggleOrderedList","_toggleTaskList","_toggleBlockquote","toggleBlockquote","_setTextAlign","setTextAlign","_normalizeLinkUrl","trimmed","_getLinkLabelFromRange","_getLinkTargetRange","extendMarkRange","_setLink","trigger","currentTarget","HTMLElement","linkRange","triggerRect","maxLeft","bottom","currentHref","getAttributes","href","currentLabel","updateComplete","then","input","select","_handleLinkEditorInput","field","dataset","_applyLink","insertTo","insertContentAt","_removeLink","unsetLink","_handleLinkEditorKeydown","_insertTable","rows","cols","insertTable","withHeaderRow","_handleImageUpload","files","initialWidth","pendingInsertPos","_insertImageAt","setImage","err","Error","_triggerImageUpload","click","_insertTableByClick","_getTableCellRow","_getTableCellCol","$pos","d","depth","index","_addTableRowAbove","addRowBefore","_addTableRowBelow","addRowAfter","_addTableColumnLeft","addColumnBefore","_addTableColumnRight","addColumnAfter","_deleteTableRow","deleteRow","_deleteTableColumn","deleteColumn","_deleteTable","deleteTable","_deleteImage","selectedImage","_getSelectedImageNode","delete","nodeSize","_insertImageAfter","insertPos","setNodeSelection","_updateSelectedImageAttributes","_setImageWidth","nextWidth","round","_handleImageWidthInput","rawValue","_setImageAlignLeft","_setImageAlignCenter","_setImageAlignRight","_getTextLabel","_getAlignLabel","textAlign","_renderImageControls","_joinToolbarGroups","groups","flatMap","_renderFormatToolbarGroup","_renderHeadingToolbarGroup","_renderAlignToolbarGroup","_renderCodeLinkImageToolbarGroup","_renderCodeToolbarButton","_renderLinkToolbarButton","_renderImageToolbarButton","_renderListToolbarGroup","_renderBlockquoteToolbarGroup","_renderTableToolbarGroup","_renderTableGrid","_getToolbarMergeKey","_renderToolbarItemByKey","_renderTextToolbar","currentMergeKey","currentGroup","flushGroup","push","rendered","mergeKey","bubbleMenu","proseMirror","isInTable","$to","hasTableInSelection","fromAncestor","toAncestor","opacity","visibility","menuRect","render","headerTemplate","shouldShowCharacterCount","cells","i","row","floor","col","isHighlight","styles","css","__decorateClass","property","attribute","prototype","safeCustomElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"blocksuite-editor.mjs","sources":["../../../../packages/components/src/editor/blocksuite-editor.ts"],"sourcesContent":["import { Editor, Extension, mergeAttributes, Node as TiptapNode } from '@tiptap/core'\nimport Blockquote from '@tiptap/extension-blockquote'\nimport Bold from '@tiptap/extension-bold'\nimport BulletList from '@tiptap/extension-bullet-list'\nimport Code from '@tiptap/extension-code'\nimport Document from '@tiptap/extension-document'\nimport Heading from '@tiptap/extension-heading'\nimport History from '@tiptap/extension-history'\nimport HorizontalRule from '@tiptap/extension-horizontal-rule'\nimport Image from '@tiptap/extension-image'\nimport Italic from '@tiptap/extension-italic'\nimport Link from '@tiptap/extension-link'\nimport ListItem from '@tiptap/extension-list-item'\nimport OrderedList from '@tiptap/extension-ordered-list'\nimport Paragraph from '@tiptap/extension-paragraph'\nimport Placeholder from '@tiptap/extension-placeholder'\nimport Strike from '@tiptap/extension-strike'\nimport { Table } from '@tiptap/extension-table'\nimport { TableCell } from '@tiptap/extension-table-cell'\nimport { TableHeader } from '@tiptap/extension-table-header'\nimport { TableRow } from '@tiptap/extension-table-row'\nimport Text from '@tiptap/extension-text'\nimport TextAlign from '@tiptap/extension-text-align'\nimport Underline from '@tiptap/extension-underline'\nimport { css, html, LitElement } from 'lit'\nimport type { EditorToolbarItem } from './toolbar'\nimport { property, state } from 'lit/decorators.js'\nimport {\n EMPTY_EDITOR_HTML,\n transformIncomingContentByFormat,\n transformOutgoingContentByFormat,\n} from './content-format'\nimport {\n DEFAULT_EDITOR_TOOLBAR,\n SIMPLE_EDITOR_TOOLBAR,\n parseEditorToolbarItems,\n} from './toolbar'\nimport type {\n ContentTransform,\n ImageUploadHandler,\n QxsBlocksuiteEditorContentFormat,\n QxsBlocksuiteEditorContentSnapshot,\n QxsBlocksuiteEditorHeaderToolbarLabelKey,\n QxsBlocksuiteEditorHeaderToolbarLabels,\n QxsBlocksuiteEditorImageUploadErrorDetail,\n QxsBlocksuiteEditorToolbarPreset,\n ToolbarMode,\n ToolbarPosition,\n} from './types'\nimport { safeCustomElement } from '../base/define'\n\ntype SlashInlineMark = 'bold' | 'italic' | 'underline' | 'strike' | 'code'\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n taskList: {\n toggleTaskList: () => ReturnType\n }\n }\n}\n\nconst DEFAULT_IMAGE_WIDTH = 560\nconst MIN_IMAGE_WIDTH = 24\nconst DEFAULT_HEADER_PLACEHOLDER = '输入内容'\nconst DEFAULT_SLASH_PLACEHOLDER = '输入 / 唤出快捷命令'\nconst DEFAULT_MIN_HEIGHT = '80px'\nconst DEFAULT_HEADER_TOOLBAR_LABELS: QxsBlocksuiteEditorHeaderToolbarLabels = {\n image: '插入图片',\n link: '插入链接',\n}\nconst HEADER_TOOLBAR_LABEL_KEYS = new Set<QxsBlocksuiteEditorHeaderToolbarLabelKey>([\n 'bold',\n 'italic',\n 'underline',\n 'strike',\n 'code',\n 'link',\n 'image',\n 'bulletList',\n 'orderedList',\n 'taskList',\n 'blockquote',\n 'table',\n])\n\nconst TaskList = TiptapNode.create({\n name: 'taskList',\n group: 'block list',\n content: 'taskItem+',\n defining: true,\n\n parseHTML() {\n return [{ tag: 'ul[data-type=\"taskList\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['ul', mergeAttributes(HTMLAttributes, { 'data-type': 'taskList' }), 0]\n },\n\n addCommands() {\n return {\n toggleTaskList: () => ({ commands }) => commands.toggleList(this.name, 'taskItem'),\n }\n },\n})\n\nconst TaskItem = TiptapNode.create({\n name: 'taskItem',\n defining: true,\n content: 'paragraph block*',\n\n addAttributes() {\n return {\n checked: {\n default: false,\n parseHTML: element => element.getAttribute('data-checked') === 'true',\n renderHTML: attributes => ({ 'data-checked': String(Boolean(attributes.checked)) }),\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'li[data-type=\"taskItem\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n const checked = Boolean(HTMLAttributes.checked)\n\n return [\n 'li',\n mergeAttributes(HTMLAttributes, { 'data-type': 'taskItem' }),\n [\n 'label',\n { contenteditable: 'false' },\n ['input', { type: 'checkbox', checked: checked ? 'checked' : null }],\n ['span'],\n ],\n ['div', 0],\n ]\n },\n\n addKeyboardShortcuts() {\n return {\n Enter: () => this.editor.commands.splitListItem(this.name),\n Tab: () => this.editor.commands.sinkListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n },\n})\n\nconst ExtendedListItem = ListItem.extend({\n addKeyboardShortcuts() {\n return {\n Enter: () => this.editor.commands.splitListItem(this.name),\n Tab: () => this.editor.commands.sinkListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n },\n})\n\nconst ExtendedImage = Image.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n width: {\n default: null,\n parseHTML: (element) => {\n const attr = element.getAttribute('width')\n const value = Number(attr)\n return Number.isFinite(value) && value > 0 ? value : null\n },\n renderHTML: attributes => attributes.width ? { width: String(attributes.width) } : {},\n },\n align: {\n default: 'left',\n parseHTML: element => element.getAttribute('data-align') || 'left',\n renderHTML: attributes => attributes.align ? { 'data-align': String(attributes.align) } : {},\n },\n }\n },\n\n renderHTML({ HTMLAttributes }) {\n const width = Number(HTMLAttributes.width)\n\n const style = [\n 'max-width:100%',\n 'height:auto',\n Number.isFinite(width) && width > 0 ? `width:${width}px` : '',\n HTMLAttributes.style || '',\n ]\n .filter(Boolean)\n .join(';')\n\n return ['img', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { style })]\n },\n})\n\n@safeCustomElement('qxs-blocksuite-editor')\nexport class QxsBlocksuiteEditor extends LitElement {\n static styles = css`\n :host {\n display: block;\n font-family: inherit;\n }\n\n .editor-wrapper {\n border: 1px solid #e3e3e3;\n border-radius: 12px;\n background: #fff;\n overflow: visible;\n position: relative;\n min-height: var(--qxs-editor-min-height, 80px);\n }\n\n .editor-wrapper:focus-within {\n border-color: var(--qxs-color-primary, #3D61E3);\n }\n\n .editor-wrapper.preview {\n border: none;\n border-radius: 0;\n background: transparent;\n }\n\n .editor-wrapper.preview .editor-content {\n padding: 8px 12px;\n min-height: unset;\n max-height: none;\n overflow: visible;\n }\n\n .editor-wrapper.toolbar-bottom .editor-header {\n border-bottom: none;\n border-top: 1px solid transparent;\n }\n\n .editor-wrapper.toolbar-bottom .editor-header.is-visible {\n border-top-color: #eef1f5;\n border-bottom-color: transparent;\n }\n\n .editor-header {\n max-height: 0;\n opacity: 0;\n overflow: hidden;\n padding: 0 16px;\n border-bottom: 1px solid transparent;\n transition:\n max-height 0.24s ease,\n opacity 0.18s ease,\n padding 0.24s ease,\n border-color 0.24s ease;\n }\n\n .editor-header.is-visible {\n max-height: 132px;\n opacity: 1;\n overflow: visible;\n padding: 10px 12px;\n border-bottom-color: #eef1f5;\n }\n\n .editor-header__inner {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n overflow: visible;\n }\n\n .editor-content {\n padding: 12px 16px;\n min-height: var(--qxs-editor-min-height, 80px);\n max-height: var(--qxs-editor-max-height, none);\n overflow-y: var(--qxs-editor-overflow-y, visible);\n cursor: text;\n }\n\n .editor-content:empty::before {\n content: attr(data-empty-hint);\n color: #c0c0c0;\n pointer-events: none;\n display: block;\n padding-top: 28px;\n text-align: center;\n }\n\n .editor-wrapper:not(.preview) .ProseMirror {\n min-height: var(--qxs-editor-min-height, 80px);\n }\n\n .editor-footer {\n display: flex;\n justify-content: flex-end;\n padding: 0 16px 12px;\n color: #909399;\n font-size: 12px;\n line-height: 1;\n }\n\n .ProseMirror p.is-editor-empty:first-child::before {\n content: attr(data-placeholder);\n color: #c0c0c0;\n pointer-events: none;\n float: left;\n height: 0;\n }\n\n .ProseMirror p.is-empty:only-child::before,\n .ProseMirror p.is-empty:only-child > br:first-child + *::before {\n content: attr(data-placeholder);\n color: #c0c0c0;\n pointer-events: none;\n float: left;\n height: 0;\n }\n\n .editor-wrapper.loading {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n background: #fafafa;\n }\n\n .loading-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n color: #909399;\n font-size: 14px;\n }\n\n .loading-spinner {\n width: 24px;\n height: 24px;\n border: 2px solid #e3e3e3;\n border-top-color: var(--qxs-color-primary, #3D61E3);\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .ProseMirror {\n outline: none;\n line-height: 1.7;\n color: #37352f;\n font-size: 15px;\n }\n\n .ProseMirror > * + * {\n margin-top: 0.5em;\n }\n\n .ProseMirror > *:first-child {\n margin-top: 0 !important;\n }\n\n .ProseMirror p {\n margin: 0;\n }\n\n .ProseMirror h1 {\n font-size: 1.875em;\n font-weight: 700;\n margin: 0 0 0.25em;\n line-height: 1.3;\n }\n\n .ProseMirror > h1:first-child {\n margin-top: 0 !important;\n line-height: 1.15;\n }\n\n .ProseMirror > p:first-child {\n margin-top: 0 !important;\n }\n\n .ProseMirror h2 {\n font-size: 1.5em;\n font-weight: 600;\n margin: 0.5em 0 0.25em;\n line-height: 1.3;\n }\n\n .ProseMirror h3 {\n font-size: 1.25em;\n font-weight: 600;\n margin: 0.5em 0 0.25em;\n line-height: 1.3;\n }\n\n .ProseMirror ul,\n .ProseMirror ol {\n padding-left: 1.5em;\n margin: 0;\n }\n\n .ProseMirror ul[data-type=\"taskList\"] {\n padding-left: 0;\n list-style: none;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n list-style: none;\n margin: 0.2em 0;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] > label {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 28px;\n flex: 0 0 18px;\n cursor: pointer;\n user-select: none;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] > label > input {\n width: 14px;\n height: 14px;\n margin: 0;\n cursor: pointer;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] > label > span {\n display: none;\n }\n\n .ProseMirror li[data-type=\"taskItem\"] > div {\n flex: 1;\n min-width: 0;\n }\n\n .ProseMirror li[data-type=\"taskItem\"][data-checked=\"true\"] > div p {\n color: #8a8f98;\n text-decoration: line-through;\n }\n\n .ProseMirror li {\n margin: 0.1em 0;\n }\n\n .ProseMirror li::marker {\n color: #37352f;\n }\n\n .ProseMirror strong {\n font-weight: 700;\n }\n\n .ProseMirror em {\n font-style: italic;\n font-synthesis: none;\n transform: skewX(-12deg);\n display: inline-block;\n }\n\n .ProseMirror u {\n text-decoration: underline;\n }\n\n .ProseMirror s {\n text-decoration: line-through;\n color: #787774;\n }\n\n .ProseMirror code {\n background: rgba(135, 131, 120, 0.14);\n color: #eb5757;\n padding: 2px 4px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', Menlo, Consolas, monospace;\n font-size: 85%;\n }\n\n .ProseMirror pre {\n background: #f6f6f7;\n border-radius: 8px;\n padding: 12px 16px;\n overflow-x: auto;\n }\n\n .ProseMirror pre code {\n background: none;\n padding: 0;\n color: #37352f;\n }\n\n .ProseMirror blockquote {\n border-left: 3px solid #e3e3e3;\n padding-left: 1em;\n margin: 0.75em 0;\n color: #787774;\n }\n\n .ProseMirror hr {\n border: none;\n border-top: 1px solid #e3e3e3;\n margin: 1.5em 0;\n }\n\n .ProseMirror img {\n max-width: 100%;\n height: auto;\n border-radius: 8px;\n }\n\n .ProseMirror img[data-align=\"left\"] {\n display: block !important;\n margin: 16px auto 16px 0 !important;\n }\n\n .ProseMirror img[data-align=\"center\"] {\n display: block !important;\n margin: 16px auto !important;\n }\n\n .ProseMirror img[data-align=\"right\"] {\n display: block !important;\n margin: 16px 0 16px auto !important;\n }\n\n .ProseMirror a {\n color: var(--qxs-color-primary, #3D61E3);\n text-decoration: underline;\n cursor: pointer;\n }\n\n .ProseMirror img.ProseMirror-selectednode {\n outline: 2px solid var(--qxs-color-primary, #3D61E3);\n outline-offset: 2px;\n box-shadow: 0 0 0 4px rgba(61, 97, 227, 0.12);\n }\n\n /* Table styles */\n .ProseMirror table {\n border-collapse: collapse;\n width: 100%;\n margin: 1em 0;\n border: 1px solid #e3e3e3;\n border-radius: 8px;\n overflow: hidden;\n }\n\n .ProseMirror th,\n .ProseMirror td {\n border: 1px solid #e3e3e3;\n padding: 8px 12px;\n text-align: left;\n vertical-align: top;\n }\n\n .ProseMirror th {\n background: #fafafa;\n font-weight: 600;\n }\n\n .ProseMirror .selectedCell {\n background: rgba(30, 150, 252, 0.1);\n }\n\n /* Table Cell Toolbar */\n .table-cell-toolbar {\n position: absolute;\n z-index: 50;\n display: flex;\n gap: 2px;\n padding: 4px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n }\n\n .table-cell-toolbar-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #606266;\n transition: all 0.15s;\n }\n\n .table-cell-toolbar-btn:hover {\n background: #ecf5ff;\n color: var(--qxs-color-primary, #3D61E3);\n }\n\n .table-cell-toolbar-btn.danger:hover {\n background: #fef0f0;\n color: #f56c6c;\n }\n\n /* Bubble Menu */\n .bubble-menu {\n position: absolute;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 4px 6px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n z-index: 100;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.15s, visibility 0.15s, transform 0.15s;\n transform: translateY(4px);\n max-width: calc(100vw - 40px);\n }\n\n .bubble-menu.is-visible {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n }\n\n .bubble-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: #37352f;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.15s;\n position: relative;\n }\n\n .bubble-btn.has-label {\n gap: 6px;\n width: auto;\n padding: 0 10px;\n white-space: nowrap;\n }\n\n .bubble-btn:hover {\n background: rgba(55, 53, 47, 0.08);\n }\n\n .bubble-btn.is-active {\n background: var(--qxs-color-primary, #3D61E3);\n color: #fff;\n }\n\n .bubble-btn.danger:hover {\n background: #fef0f0;\n color: #f56c6c;\n }\n\n .bubble-btn svg {\n width: 16px;\n height: 16px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n flex: 0 0 auto;\n }\n\n .bubble-btn__label {\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n }\n\n .bubble-divider {\n width: 1px;\n height: 16px;\n background: #e3e3e3;\n margin: 0 3px;\n }\n\n /* Dropdown */\n .bubble-dropdown {\n position: relative;\n }\n\n .bubble-dropdown-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 0 6px;\n height: 28px;\n border: none;\n background: transparent;\n color: #37352f;\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n font-family: inherit;\n transition: all 0.15s;\n white-space: nowrap;\n }\n\n .bubble-dropdown-btn.has-label {\n gap: 6px;\n padding: 0 10px;\n }\n\n .bubble-dropdown-btn:hover {\n background: rgba(55, 53, 47, 0.08);\n }\n\n .bubble-dropdown-btn svg {\n width: 12px;\n height: 12px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n .bubble-dropdown-btn__label {\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n }\n\n .bubble-dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n margin-top: 4px;\n min-width: 120px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n padding: 4px;\n opacity: 0;\n visibility: hidden;\n transform: translateY(-4px);\n transition: all 0.15s;\n z-index: 101;\n }\n\n .bubble-dropdown:hover .bubble-dropdown-menu,\n .bubble-dropdown.is-open .bubble-dropdown-menu {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n }\n\n .bubble-dropdown-item {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 6px 8px;\n border: none;\n background: transparent;\n color: #37352f;\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n font-family: inherit;\n text-align: left;\n transition: all 0.15s;\n }\n\n .bubble-dropdown-item:hover {\n background: rgba(55, 53, 47, 0.08);\n }\n\n .bubble-dropdown-item.is-active {\n background: var(--qxs-color-primary, #3D61E3);\n color: #fff;\n }\n\n .bubble-dropdown-item svg {\n width: 16px;\n height: 16px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n /* Keep the file input programmatically clickable inside shadow hosts. */\n .image-input {\n position: absolute;\n inset: 0 auto auto 0;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: 0;\n opacity: 0;\n pointer-events: none;\n }\n\n .table-grid-preview {\n display: grid;\n grid-template-columns: repeat(10, 18px);\n gap: 2px;\n padding: 8px;\n }\n\n .table-grid-preview .table-cell {\n width: 18px;\n height: 18px;\n border: 1px solid #e3e3e3;\n border-radius: 2px;\n background: #fff;\n cursor: pointer;\n transition: all 0.1s;\n }\n\n .table-grid-preview .table-cell:hover {\n background: rgba(30, 150, 252, 0.3);\n border-color: var(--qxs-color-primary, #3D61E3);\n }\n\n .table-grid-preview .table-cell.selected {\n background: rgba(30, 150, 252, 0.15);\n border-color: rgba(30, 150, 252, 0.5);\n }\n\n .table-size-hint {\n text-align: center;\n padding: 4px 8px 6px;\n font-size: 10px;\n color: #8c8c8c;\n }\n\n .image-size-control {\n display: flex;\n align-items: center;\n gap: 6px;\n padding-left: 8px;\n margin-left: 2px;\n border-left: 1px solid #e3e3e3;\n white-space: nowrap;\n }\n\n .image-size-label {\n font-size: 12px;\n color: #7a7f88;\n }\n\n .image-size-range {\n width: 72px;\n height: 26px;\n padding: 0 8px;\n border: 1px solid #d8dde6;\n border-radius: 6px;\n font-size: 12px;\n color: #37352f;\n background: #fff;\n outline: none;\n }\n\n .image-size-range:focus {\n border-color: var(--qxs-color-primary, #3D61E3);\n }\n\n .link-editor {\n position: absolute;\n z-index: 120;\n display: grid;\n gap: 8px;\n min-width: 320px;\n padding: 10px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 10px;\n box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14);\n }\n\n .link-editor__field {\n display: grid;\n gap: 4px;\n }\n\n .link-editor__label {\n font-size: 12px;\n color: #6b7280;\n line-height: 1;\n }\n\n .link-editor__input {\n min-width: 0;\n height: 32px;\n padding: 0 10px;\n border: 1px solid #d8dde6;\n border-radius: 8px;\n outline: none;\n font-size: 13px;\n color: #37352f;\n background: #fff;\n }\n\n .link-editor__input:focus {\n border-color: var(--qxs-color-primary, #3D61E3);\n }\n\n .link-editor__actions {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .link-editor__action {\n height: 32px;\n padding: 0 12px;\n border: 1px solid #d8dde6;\n border-radius: 8px;\n background: #fff;\n color: #4b5563;\n font-size: 12px;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n }\n\n .link-editor__action:hover {\n border-color: #c3cad5;\n background: #f8fafc;\n }\n\n .link-editor__action.primary {\n border-color: var(--qxs-color-primary, #3D61E3);\n background: var(--qxs-color-primary, #3D61E3);\n color: #fff;\n }\n\n .link-editor__action.danger {\n color: #f56c6c;\n }\n\n /* Image Toolbar */\n .image-toolbar {\n position: absolute;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 4px 6px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 6px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n z-index: 100;\n transform: translateX(-50%);\n }\n\n .image-toolbar-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #595959;\n transition: all 0.15s;\n }\n\n .image-toolbar-btn:hover {\n background: #f5f5f5;\n color: var(--qxs-color-primary, #3D61E3);\n }\n\n .image-toolbar-btn.danger:hover {\n background: #fff1f0;\n color: #ff4d4f;\n }\n\n .image-toolbar-btn svg {\n width: 16px;\n height: 16px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n .image-toolbar-divider {\n width: 1px;\n height: 20px;\n background: #e3e3e3;\n margin: 0 4px;\n }\n\n .image-control-label {\n display: inline-flex;\n align-items: center;\n padding: 0 4px;\n font-size: 12px;\n color: #909399;\n user-select: none;\n white-space: nowrap;\n }\n\n /* Image More Menu */\n .image-more-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n padding: 4px;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 6px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n z-index: 101;\n min-width: 120px;\n }\n\n .image-more-menu-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: none;\n background: transparent;\n width: 100%;\n text-align: left;\n font-size: 13px;\n color: #595959;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .image-more-menu-item:hover {\n background: #f5f5f5;\n color: var(--qxs-color-primary, #3D61E3);\n }\n\n .image-more-menu-item svg {\n width: 14px;\n height: 14px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\n }\n\n /* Selected Image */\n .ProseMirror img.selected {\n outline: 2px solid var(--qxs-color-primary, #3D61E3);\n outline-offset: 2px;\n }\n `\n\n @property({ type: String, attribute: 'content' })\n content = ''\n\n @property({ type: String, attribute: 'model-value' })\n 'model-value' = ''\n\n @property({ type: String, attribute: 'placeholder' })\n placeholder = DEFAULT_HEADER_PLACEHOLDER\n\n @property({ type: String, attribute: 'toolbar-mode' })\n 'toolbar-mode': ToolbarMode = 'header'\n\n @property({ attribute: 'toolbar' })\n toolbar: string | EditorToolbarItem[] = ''\n\n @property({ type: String, attribute: 'toolbar-preset' })\n 'toolbar-preset': QxsBlocksuiteEditorToolbarPreset = 'full'\n\n @property({ attribute: 'header-toolbar-labels' })\n 'header-toolbar-labels': string | QxsBlocksuiteEditorHeaderToolbarLabels = DEFAULT_HEADER_TOOLBAR_LABELS\n\n private _lastInvalidHeaderToolbarLabelsSource: unknown = undefined\n\n @property({ type: String, attribute: 'header-always-visible' })\n 'header-always-visible': boolean | string = 'true'\n\n @property({ type: String, attribute: 'use-model' })\n 'use-model': boolean | string = 'false'\n\n @property({ type: String, attribute: 'readonly' })\n readonly: boolean | string = 'false'\n\n @property({ type: String, attribute: 'preview' })\n preview: boolean | string = 'false'\n\n @property({ attribute: 'editable' })\n editable: boolean | string | null = null\n\n @property({ type: String, attribute: 'min-height' })\n 'min-height' = DEFAULT_MIN_HEIGHT\n\n @property({ type: String, attribute: 'max-height' })\n 'max-height' = ''\n\n @property({ type: String, attribute: 'show-character-count' })\n 'show-character-count': boolean | string = 'false'\n\n @property({ type: String, attribute: 'toolbar-position' })\n 'toolbar-position': ToolbarPosition = 'top'\n\n @property({ type: String, attribute: 'custom-styles' })\n 'custom-styles' = ''\n\n @property({ type: String, attribute: 'content-format' })\n 'content-format': QxsBlocksuiteEditorContentFormat = 'html'\n\n @property({ type: Object, attribute: 'deserialize-content' })\n 'deserialize-content': ContentTransform | null = null\n\n @property({ type: Object, attribute: 'serialize-content' })\n 'serialize-content': ContentTransform | null = null\n\n private _injectedStyleEl: HTMLStyleElement | null = null\n\n private _injectCustomStyles() {\n const shadow = this.shadowRoot\n if (!shadow) { return }\n\n if (this._injectedStyleEl) {\n this._injectedStyleEl.remove()\n this._injectedStyleEl = null\n }\n\n if (!this['custom-styles']) { return }\n\n const styleEl = document.createElement('style')\n styleEl.textContent = this['custom-styles']\n shadow.appendChild(styleEl)\n this._injectedStyleEl = styleEl\n }\n\n private get _useModelValue(): boolean {\n return this['use-model'] === true || this['use-model'] === 'true' || this['use-model'] === '' || this.hasAttribute('use-model')\n }\n\n private get _readonlyValue(): boolean {\n return this.readonly !== false && this.readonly !== 'false'\n }\n\n private get _previewValue(): boolean {\n return this.preview !== false && this.preview !== 'false'\n }\n\n private get _editableValue(): boolean | null {\n if (this.editable === null || this.editable === undefined) {\n return null\n }\n\n return this.editable !== false && this.editable !== 'false'\n }\n\n private get _isEditable(): boolean {\n if (this._previewValue) {\n return false\n }\n\n if (this._editableValue !== null) {\n return this._editableValue\n }\n\n return !this._readonlyValue\n }\n\n private get _toolbarModeValue(): ToolbarMode {\n return this['toolbar-mode'] === 'header' ? 'header' : 'slash'\n }\n\n private get _headerAlwaysVisibleValue(): boolean {\n return this['header-always-visible'] === true\n || this['header-always-visible'] === 'true'\n || this['header-always-visible'] === ''\n || this.hasAttribute('header-always-visible')\n }\n\n private get _toolbarPositionValue(): ToolbarPosition {\n return this['toolbar-position'] === 'bottom' ? 'bottom' : 'top'\n }\n\n private get _toolbarPresetValue(): QxsBlocksuiteEditorToolbarPreset {\n if (this['toolbar-preset'] === 'simple') {\n return 'simple'\n }\n\n if (this['toolbar-preset'] === 'none') {\n return 'none'\n }\n\n return 'full'\n }\n\n private get _contentFormatValue(): QxsBlocksuiteEditorContentFormat {\n if (this['content-format'] === 'markdown') {\n return 'markdown'\n }\n\n if (this['content-format'] === 'custom') {\n return 'custom'\n }\n\n return 'html'\n }\n\n private get _showCharacterCountValue(): boolean {\n return this['show-character-count'] === true\n || this['show-character-count'] === 'true'\n || this['show-character-count'] === ''\n || this.hasAttribute('show-character-count')\n }\n\n private get _resolvedMinHeight(): string {\n return this['min-height']?.trim() || DEFAULT_MIN_HEIGHT\n }\n\n private get _resolvedMaxHeight(): string {\n return this['max-height']?.trim() || 'none'\n }\n\n private get _wrapperStyleValue(): string {\n const overflowY = this['max-height']?.trim() ? 'auto' : 'visible'\n\n return [\n `--qxs-editor-min-height: ${this._resolvedMinHeight}`,\n `--qxs-editor-max-height: ${this._resolvedMaxHeight}`,\n `--qxs-editor-overflow-y: ${overflowY}`,\n ].join('; ')\n }\n\n private get _resolvedPlaceholder(): string {\n if (\n this.placeholder\n && this.placeholder !== DEFAULT_HEADER_PLACEHOLDER\n && this.placeholder !== DEFAULT_SLASH_PLACEHOLDER\n ) {\n return this.placeholder\n }\n return this._toolbarModeValue === 'header'\n ? DEFAULT_HEADER_PLACEHOLDER\n : DEFAULT_SLASH_PLACEHOLDER\n }\n\n private get _toolbarItemsValue(): EditorToolbarItem[] {\n if (Array.isArray(this.toolbar)) {\n return parseEditorToolbarItems(this.toolbar)\n }\n\n if (typeof this.toolbar === 'string' && this.toolbar.trim()) {\n return parseEditorToolbarItems(this.toolbar)\n }\n\n if (this._toolbarPresetValue === 'simple') {\n return [...SIMPLE_EDITOR_TOOLBAR]\n }\n\n if (this._toolbarPresetValue === 'none') {\n return []\n }\n\n return [...DEFAULT_EDITOR_TOOLBAR]\n }\n\n private _hasToolbarItem(item: EditorToolbarItem): boolean {\n return this._toolbarItemsValue.includes(item)\n }\n\n private get _headerToolbarLabelsValue(): QxsBlocksuiteEditorHeaderToolbarLabels {\n const source = this['header-toolbar-labels']\n if (!source) {\n return {}\n }\n\n let parsed: unknown = source\n if (typeof source === 'string') {\n if (source === '[object Object]') {\n this._warnInvalidHeaderToolbarLabels(\n source,\n 'received \"[object Object]\"; Vue hosts should pass object values with `.prop`, for example `:header-toolbar-labels.prop=\"headerToolbarLabels\"`',\n )\n return {}\n }\n\n try {\n parsed = JSON.parse(source)\n }\n catch (error) {\n this._warnInvalidHeaderToolbarLabels(source, 'parse failed, fallback to empty map', error)\n return {}\n }\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return {}\n }\n\n const labels: QxsBlocksuiteEditorHeaderToolbarLabels = {}\n for (const [key, value] of Object.entries(parsed)) {\n if (\n HEADER_TOOLBAR_LABEL_KEYS.has(key as QxsBlocksuiteEditorHeaderToolbarLabelKey)\n && typeof value === 'string'\n && value.trim()\n ) {\n labels[key as QxsBlocksuiteEditorHeaderToolbarLabelKey] = value.trim()\n }\n }\n\n return labels\n }\n\n private _warnInvalidHeaderToolbarLabels(source: unknown, message: string, error?: unknown) {\n if (this._lastInvalidHeaderToolbarLabelsSource === source) {\n return\n }\n\n this._lastInvalidHeaderToolbarLabelsSource = source\n if (error) {\n console.warn(`[qxs-blocksuite-editor] header-toolbar-labels ${message}`, error)\n return\n }\n\n console.warn(`[qxs-blocksuite-editor] header-toolbar-labels ${message}`)\n }\n\n private _getHeaderToolbarLabel(key: QxsBlocksuiteEditorHeaderToolbarLabelKey): string {\n if (this._toolbarModeValue !== 'header') {\n return ''\n }\n\n return this._headerToolbarLabelsValue[key] || ''\n }\n\n private _renderToolbarButton(\n key: QxsBlocksuiteEditorHeaderToolbarLabelKey,\n options: {\n title: string\n icon: unknown\n active?: boolean\n danger?: boolean\n onClick: (event: MouseEvent) => void\n },\n ) {\n const label = this._getHeaderToolbarLabel(key)\n const className = [\n 'bubble-btn',\n options.active ? 'is-active' : '',\n options.danger ? 'danger' : '',\n label ? 'has-label' : '',\n ]\n .filter(Boolean)\n .join(' ')\n\n return html`\n <button class=${className} @click=${options.onClick} title=${options.title}>\n ${options.icon}\n ${label ? html`<span class=\"bubble-btn__label\">${label}</span>` : null}\n </button>\n `\n }\n\n private _transformIncomingContent(value: string | null | undefined): string {\n const source = value || ''\n const transform = this['deserialize-content']\n\n if (!transform) {\n return transformIncomingContentByFormat(source, this._contentFormatValue)\n }\n\n try {\n return transform(source) || EMPTY_EDITOR_HTML\n }\n catch (error) {\n console.warn('[qxs-blocksuite-editor] deserialize-content failed, fallback to raw content', error)\n return transformIncomingContentByFormat(source, this._contentFormatValue)\n }\n }\n\n private _transformOutgoingContent(value: string): string {\n const transform = this['serialize-content']\n\n if (!transform) {\n return transformOutgoingContentByFormat(value, this._contentFormatValue)\n }\n\n try {\n return transform(value)\n }\n catch (error) {\n console.warn('[qxs-blocksuite-editor] serialize-content failed, fallback to raw html', error)\n return transformOutgoingContentByFormat(value, this._contentFormatValue)\n }\n }\n\n private _getEditorCharacterCount(): number {\n return this._editor?.getText().length ?? 0\n }\n\n @property({ type: Object, attribute: 'upload-image' })\n 'upload-image': ImageUploadHandler = async (file: File) => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = e => resolve(e.target?.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n }\n\n @state() private _editor: Editor | null = null\n private _pendingContent: string | null = null\n private _tableRows = 3\n private _tableCols = 3\n @state() private _hoverRow = 0\n @state() private _hoverCol = 0\n @state() private _tableDropdownOpen = false\n @state() private _tableCellToolbar: { x: number, y: number, visible: boolean, cellRow: number, cellCol: number } = { x: 0, y: 0, visible: false, cellRow: 0, cellCol: 0 }\n @state() private _imageToolbar: { x: number, y: number, visible: boolean } = { x: 0, y: 0, visible: false }\n @state() private _linkEditor = { x: 0, y: 0, visible: false, url: '', label: '' }\n @state() private _isEditorFocused = false\n @state() private _selectedImage: { pos: number, width: number, align: string } | null = null\n private _hasSlashCommand = false\n private _slashCommandRange: { from: number, to: number } | null = null\n private _slashInlineMarkState: { type: SlashInlineMark, lineStart: number, startPos: number } | null = null\n private _isComposingText = false\n private _isUpdating = false\n private _pendingImageInsertPos: number | null = null\n private _linkSelection: { from: number, to: number } | null = null\n private _preserveFocusOnInternalClick = false\n\n private _initEditor() {\n if (this._editor) { return }\n\n const el = this.shadowRoot?.querySelector<HTMLElement>('.editor-content')\n if (!el) {\n requestAnimationFrame(() => this._initEditor())\n return\n }\n\n while (el.firstChild) {\n el.removeChild(el.firstChild)\n }\n\n const useModel = this._useModelValue\n const modelValue = this.getAttribute('model-value') ?? this['model-value']\n const contentValue = this.content\n\n const initialContent = useModel\n ? this._transformIncomingContent(this._pendingContent ?? modelValue)\n : this._transformIncomingContent(this._pendingContent ?? contentValue)\n\n const extensions: any[] = [\n Document,\n Paragraph,\n Text,\n Bold,\n Italic,\n Underline,\n Strike,\n Code,\n Heading.configure({ levels: [1, 2, 3] }),\n BulletList,\n OrderedList,\n TaskList,\n TaskItem,\n ExtendedListItem,\n Blockquote,\n HorizontalRule,\n History,\n ExtendedImage.configure({\n inline: false,\n allowBase64: true,\n }),\n Link.extend({\n inclusive: false,\n }).configure({\n openOnClick: false,\n HTMLAttributes: {\n rel: 'noopener noreferrer',\n },\n }),\n TextAlign.configure({\n types: ['heading', 'paragraph'],\n }),\n Table.configure({\n resizable: true,\n }),\n TableRow,\n TableCell,\n TableHeader,\n Placeholder.configure({\n placeholder: this._resolvedPlaceholder,\n }),\n ]\n\n this._editor = new Editor({\n element: el,\n extensions,\n editable: this._isEditable,\n content: initialContent,\n })\n\n this._editor.view.dom.addEventListener('compositionstart', this._handleCompositionStart)\n this._editor.view.dom.addEventListener('compositionend', this._handleCompositionEnd)\n\n this._pendingContent = null\n\n this._editor.on('selectionUpdate', () => {\n this._syncSlashInlineMarkState()\n this._restoreSlashInlineMarkIfNeeded()\n if (this._toolbarModeValue === 'slash') {\n this._updateBubbleMenuPosition()\n }\n if (this._editor?.isActive('table')) {\n this._showTableCellToolbar()\n }\n else {\n this._hideTableCellToolbar()\n }\n this._syncImageSelectionState()\n })\n\n this._editor.on('transaction', () => {\n if (this._editor?.isActive('table')) {\n this._showTableCellToolbar()\n }\n else {\n this._hideTableCellToolbar()\n }\n this._checkSlashCommand()\n this._syncSlashInlineMarkState()\n this._restoreSlashInlineMarkIfNeeded()\n this._setupTableEdgeDetection()\n this._syncImageSelectionState()\n })\n\n this._editor.on('update', () => {\n this._emitContentChange()\n })\n }\n\n private _tableEdgeDetectionSetup = false\n\n private _toggleTaskItemChecked(event: Event) {\n const target = event.target\n const editor = this._editor\n if (!(target instanceof HTMLInputElement) || target.type !== 'checkbox' || !editor) {\n return\n }\n\n const taskItem = target.closest('li[data-type=\"taskItem\"]')\n if (!taskItem) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n const basePos = editor.view.posAtDOM(taskItem, 0)\n const searchFrom = Math.max(0, basePos - 2)\n const searchTo = Math.min(editor.state.doc.content.size, basePos + 2)\n\n let taskItemPos: number | null = null\n editor.state.doc.nodesBetween(searchFrom, searchTo, (node, pos) => {\n if (node.type.name === 'taskItem') {\n taskItemPos = pos\n return false\n }\n return undefined\n })\n\n if (taskItemPos === null) {\n return\n }\n\n const node = editor.state.doc.nodeAt(taskItemPos)\n if (!node || node.type.name !== 'taskItem') {\n return\n }\n\n editor.view.dispatch(editor.state.tr.setNodeMarkup(taskItemPos, undefined, {\n ...node.attrs,\n checked: !node.attrs.checked,\n }))\n }\n\n private _emitContentChange() {\n if (!this._editor) { return }\n const snapshot = this.getContentSnapshot()\n\n if (this._showCharacterCountValue) {\n this.requestUpdate()\n }\n\n this.dispatchEvent(new CustomEvent<QxsBlocksuiteEditorContentSnapshot>('content-update', {\n detail: snapshot,\n bubbles: true,\n composed: true,\n }))\n\n this.dispatchEvent(new CustomEvent('content-change', {\n detail: snapshot.value,\n bubbles: true,\n composed: true,\n }))\n }\n\n private _setupTableEdgeDetection() {\n const editorContent = this.shadowRoot?.querySelector('.editor-content')\n const editorWrapper = this.shadowRoot?.querySelector('.editor-wrapper')\n if (!editorContent || this._tableEdgeDetectionSetup) { return }\n\n this._tableEdgeDetectionSetup = true\n\n const handleEditorClick = (event: Event) => {\n this._toggleTaskItemChecked(event)\n\n const target = event.target\n if (\n target instanceof Element\n && target.closest('.editor-header, .bubble-menu, .table-cell-toolbar, .image-toolbar, .link-editor')\n ) {\n return\n }\n if (!this._isEditable) {\n return\n }\n this._editor?.chain().focus().run()\n }\n\n editorContent.addEventListener('click', handleEditorClick as EventListener)\n editorWrapper?.addEventListener('click', handleEditorClick as EventListener)\n }\n\n private _handleWrapperFocusIn() {\n this._preserveFocusOnInternalClick = false\n this._isEditorFocused = true\n }\n\n private _handleHeaderToolbarMouseDown(event: MouseEvent) {\n if (!this._isEditable) {\n return\n }\n\n const target = event.target\n if (!(target instanceof Element) || !target.closest('button, .bubble-dropdown, .table-cell')) {\n return\n }\n\n // Keep the ProseMirror selection alive while using the header toolbar.\n event.preventDefault()\n this._preserveFocusOnInternalClick = true\n requestAnimationFrame(() => {\n this._preserveFocusOnInternalClick = false\n })\n }\n\n private _handleWrapperMouseDown(event: MouseEvent) {\n const target = event.target\n if (\n !this._isEditable\n || !(target instanceof Element)\n || target.closest('.editor-header, .bubble-menu, .table-cell-toolbar, .image-toolbar, .link-editor')\n ) {\n return\n }\n\n this._preserveFocusOnInternalClick = true\n requestAnimationFrame(() => {\n this._preserveFocusOnInternalClick = false\n })\n }\n\n private _handleWrapperFocusOut(event: FocusEvent) {\n const nextTarget = event.relatedTarget as Node | null\n const wrapper = this.shadowRoot?.querySelector('.editor-wrapper')\n if (this._preserveFocusOnInternalClick) {\n return\n }\n if (nextTarget && wrapper?.contains(nextTarget)) {\n return\n }\n this._isEditorFocused = false\n this._tableDropdownOpen = false\n this._selectedImage = null\n this._hideImageToolbar()\n this._closeLinkEditor()\n }\n\n private _isHeaderVisible(): boolean {\n return this._toolbarModeValue === 'header'\n && !this._previewValue\n && (\n this._headerAlwaysVisibleValue\n || this._isEditorFocused\n || this._tableDropdownOpen\n || Boolean(this._selectedImage)\n )\n }\n\n private _getImageSelection() {\n const editor = this._editor\n const selection: any = editor?.state.selection\n if (!editor || !selection?.node || selection.node.type?.name !== 'image') {\n return null\n }\n\n return {\n pos: selection.from,\n attrs: selection.node.attrs ?? {},\n }\n }\n\n private _getImageMaxWidth() {\n const editorContent = this.shadowRoot?.querySelector<HTMLElement>('.editor-content')\n const availableWidth = (editorContent?.clientWidth ?? DEFAULT_IMAGE_WIDTH) - 32\n return Math.max(MIN_IMAGE_WIDTH, Math.min(DEFAULT_IMAGE_WIDTH, availableWidth))\n }\n\n private async _getImageNaturalWidth(file: File) {\n return await new Promise<number | null>((resolve) => {\n const objectUrl = URL.createObjectURL(file)\n const image = new window.Image()\n\n image.onload = () => {\n const naturalWidth = image.naturalWidth\n URL.revokeObjectURL(objectUrl)\n resolve(Number.isFinite(naturalWidth) && naturalWidth > 0 ? naturalWidth : null)\n }\n\n image.onerror = () => {\n URL.revokeObjectURL(objectUrl)\n resolve(null)\n }\n\n image.src = objectUrl\n })\n }\n\n private _syncImageSelectionState() {\n const selection = this._getImageSelection()\n if (!selection) {\n this._selectedImage = null\n if (this._toolbarModeValue === 'slash') {\n this._hideImageToolbar()\n }\n return\n }\n\n const width = Number(selection.attrs.width)\n const align = String(selection.attrs.align || 'left')\n this._selectedImage = {\n pos: selection.pos,\n width: Number.isFinite(width) && width > 0 ? width : this._getImageMaxWidth(),\n align,\n }\n\n if (this._toolbarModeValue !== 'slash') {\n this._hideImageToolbar()\n return\n }\n\n const editor = this._editor\n const wrapperRect = this.shadowRoot?.querySelector('.editor-wrapper')?.getBoundingClientRect()\n if (!editor || !wrapperRect) { return }\n const coords = editor.view.coordsAtPos(selection.pos)\n const x = coords.left - wrapperRect.left + (coords.right - coords.left) / 2\n const y = coords.top - wrapperRect.top - 40\n this._showImageToolbar({ x, y })\n }\n\n private _clearSlashCommandText() {\n if (!this._editor || !this._slashCommandRange) { return }\n const { from, to } = this._slashCommandRange\n this._editor.chain().focus().deleteRange({ from, to }).run()\n this._hasSlashCommand = false\n this._slashCommandRange = null\n }\n\n private _checkSlashCommand() {\n if (!this._editor) { return }\n const { selection } = this._editor.state\n if (!selection.empty) {\n this._hasSlashCommand = false\n this._slashCommandRange = null\n return\n }\n\n const { $from } = selection as any\n const textBefore = $from.parent.textBetween(0, $from.parentOffset, ' ', ' ')\n const matched = /(?:^|\\s)(\\/\\S*)$/.exec(textBefore)\n\n if (!matched) {\n this._hasSlashCommand = false\n this._slashCommandRange = null\n return\n }\n\n const slashText = matched[1]\n this._hasSlashCommand = true\n this._slashCommandRange = {\n from: selection.from - slashText.length,\n to: selection.from,\n }\n }\n\n firstUpdated() {\n this._injectCustomStyles()\n queueMicrotask(() => {\n if (this.isConnected) {\n this._initEditor()\n }\n })\n }\n\n updated(changed: Map<string, unknown>) {\n if (changed.has('custom-styles')) {\n this._injectCustomStyles()\n }\n\n if (this._editor) {\n if (\n changed.has('content')\n || (changed.has('model-value') && this._useModelValue)\n || changed.has('deserialize-content')\n || changed.has('content-format')\n ) {\n const nextValue = this._useModelValue ? this['model-value'] : this.content\n const newContent = this._transformIncomingContent(nextValue)\n const isFormatReconfigured = changed.has('deserialize-content') || changed.has('content-format')\n const isControlledEcho = !isFormatReconfigured && (nextValue ?? '') === this.getContent()\n\n if (!isControlledEcho && newContent !== this._editor.getHTML()) {\n this._editor.commands.setContent(newContent)\n }\n }\n if (changed.has('readonly') || changed.has('preview') || changed.has('editable')) {\n this._editor.setEditable(this._isEditable)\n }\n return\n }\n\n // 编辑器未初始化时,只保存待处理内容,不重复初始化\n if (changed.has('content')) {\n this._pendingContent = this.content\n }\n\n if (changed.has('model-value') && this._useModelValue) {\n this._pendingContent = this['model-value']\n }\n\n // 只有在 firstUpdated 时才会初始化编辑器\n // 这里不再重复调用 _initEditor()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n const editorDom = this._editor?.view?.dom\n editorDom?.removeEventListener('compositionstart', this._handleCompositionStart)\n editorDom?.removeEventListener('compositionend', this._handleCompositionEnd)\n this._editor?.destroy()\n this._editor = null\n }\n\n getContent(): string {\n return this.getContentSnapshot().value\n }\n\n getContentSnapshot(): QxsBlocksuiteEditorContentSnapshot {\n const html = this._editor?.getHTML() ?? ''\n const text = this._editor?.getText().trim() ?? ''\n\n return {\n value: html ? this._transformOutgoingContent(html) : '',\n html,\n text,\n format: this._contentFormatValue,\n }\n }\n\n forceUpdate(): void {\n this.requestUpdate()\n if (this._editor) {\n const newContent = this._transformIncomingContent(this._useModelValue ? this['model-value'] : this.content)\n if (newContent !== this._editor.getHTML()) {\n this._editor.commands.setContent(newContent)\n }\n }\n }\n\n private _applyFormat(command: () => void) {\n this._clearSlashCommandText()\n this._clearSlashInlineMarkState(true)\n command()\n }\n\n private _getCurrentLineStart(editor: Editor) {\n const { selection } = editor.state\n if (!selection.empty) { return null }\n return selection.$from.start()\n }\n\n private _handleCompositionStart = () => {\n this._isComposingText = true\n }\n\n private _handleCompositionEnd = () => {\n this._isComposingText = false\n requestAnimationFrame(() => {\n this._syncSlashInlineMarkState()\n this._restoreSlashInlineMarkIfNeeded()\n })\n }\n\n private _getSlashCommandContext() {\n const editor = this._editor\n const range = this._slashCommandRange\n if (!editor || !range) { return null }\n\n const $from = editor.state.doc.resolve(range.from)\n return {\n lineFrom: $from.start(),\n lineTo: range.from,\n }\n }\n\n private _clearSlashInlineMarkState(force = false) {\n const editor = this._editor\n const state = this._slashInlineMarkState\n if (!editor || !state) { return }\n\n const { selection } = editor.state\n const currentLineStart = this._getCurrentLineStart(editor)\n if (!force && currentLineStart === state.lineStart && selection.empty && selection.to >= state.startPos) {\n return\n }\n\n this._slashInlineMarkState = null\n\n const pos = editor.state.selection.to\n let chain = editor.chain().focus().setTextSelection({ from: pos, to: pos })\n\n switch (state.type) {\n case 'bold':\n chain = chain.unsetBold()\n break\n case 'italic':\n chain = chain.unsetItalic()\n break\n case 'underline':\n chain = chain.unsetUnderline()\n break\n case 'strike':\n chain = chain.unsetStrike()\n break\n case 'code':\n chain = chain.unsetCode()\n break\n }\n\n chain.run()\n }\n\n private _runInlineMarkAction(\n type: SlashInlineMark,\n chain: ReturnType<Editor['chain']>,\n mode: 'set' | 'unset',\n ) {\n switch (type) {\n case 'bold':\n return mode === 'set' ? chain.setBold() : chain.unsetBold()\n case 'italic':\n return mode === 'set' ? chain.setItalic() : chain.unsetItalic()\n case 'underline':\n return mode === 'set' ? chain.setUnderline() : chain.unsetUnderline()\n case 'strike':\n return mode === 'set' ? chain.setStrike() : chain.unsetStrike()\n case 'code':\n return mode === 'set' ? chain.setCode() : chain.unsetCode()\n }\n }\n\n private _syncSlashInlineMarkState() {\n if (!this._slashInlineMarkState || !this._editor) { return }\n if (this._isComposingText) { return }\n if (this._shouldEndSlashInlineMarkAtCursor()) {\n this._clearSlashInlineMarkState(true)\n return\n }\n this._clearSlashInlineMarkState()\n }\n\n private _shouldEndSlashInlineMarkAtCursor() {\n const editor = this._editor\n const state = this._slashInlineMarkState\n if (!editor || !state) { return false }\n\n const { selection } = editor.state\n const currentLineStart = this._getCurrentLineStart(editor)\n if (!selection.empty || currentLineStart !== state.lineStart || selection.to <= state.startPos) {\n return false\n }\n\n const charBefore = editor.state.doc.textBetween(selection.to - 1, selection.to, '\\n', '\\n')\n return /\\s/.test(charBefore)\n }\n\n private _hasInlineMarkAtCursor(type: SlashInlineMark) {\n const editor = this._editor\n if (!editor) { return false }\n\n const markType = editor.schema.marks[type]\n if (!markType) { return false }\n\n const { selection, storedMarks } = editor.state\n if (!selection.empty) { return false }\n\n const marks = storedMarks ?? selection.$from.marks()\n return marks.some(mark => mark.type === markType)\n }\n\n private _restoreSlashInlineMarkIfNeeded() {\n const editor = this._editor\n const state = this._slashInlineMarkState\n if (!editor || !state) { return }\n\n const { selection } = editor.state\n const currentLineStart = this._getCurrentLineStart(editor)\n if (!selection.empty || currentLineStart !== state.lineStart || selection.to < state.startPos) { return }\n if (this._hasInlineMarkAtCursor(state.type)) { return }\n\n const pos = editor.state.selection.to\n this._runInlineMarkAction(\n state.type,\n editor.chain().focus().setTextSelection({ from: pos, to: pos }),\n 'set',\n ).run()\n }\n\n private _setInlineMarkState(type: SlashInlineMark, startPos: number) {\n const lineStart = this._getCurrentLineStart(this._editor!)\n this._slashInlineMarkState = lineStart === null ? null : { type, lineStart, startPos }\n }\n\n private _applyInlineMarkToCurrentLine(type: SlashInlineMark, mode: 'set' | 'unset') {\n const editor = this._editor\n if (!editor) { return false }\n\n const { selection } = editor.state\n if (!selection.empty) {\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection({ from: selection.from, to: selection.to }),\n mode,\n ).run()\n if (mode === 'unset') {\n this._clearSlashInlineMarkState(true)\n }\n return true\n }\n\n const cursorPos = selection.from\n const $from = editor.state.doc.resolve(cursorPos)\n const lineRange = { from: $from.start(), to: $from.end() }\n\n this._clearSlashInlineMarkState(true)\n\n if (lineRange.from < lineRange.to) {\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection(lineRange),\n mode,\n ).run()\n }\n\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection({ from: cursorPos, to: cursorPos }),\n mode,\n ).run()\n\n if (mode === 'set') {\n this._setInlineMarkState(type, cursorPos)\n }\n\n return true\n }\n\n private _toggleToolbarInlineMark(type: SlashInlineMark) {\n return this._applyInlineMarkToCurrentLine(\n type,\n this._hasInlineMarkAtCursor(type) ? 'unset' : 'set',\n )\n }\n\n private _applySlashInlineMark(\n type: SlashInlineMark,\n ) {\n const editor = this._editor\n const context = this._getSlashCommandContext()\n if (!editor || !context) { return false }\n\n this._clearSlashCommandText()\n this._clearSlashInlineMarkState(true)\n\n const cursorPos = editor.state.selection.to\n const lineRange = {\n from: context.lineFrom,\n to: editor.state.doc.resolve(cursorPos).end(),\n }\n\n if (lineRange.from < lineRange.to) {\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection(lineRange),\n 'set',\n ).run()\n }\n\n this._runInlineMarkAction(\n type,\n editor.chain().focus().setTextSelection({ from: cursorPos, to: cursorPos }),\n 'set',\n ).run()\n\n this._setInlineMarkState(type, cursorPos)\n return true\n }\n\n private _applySlashLineBlock(\n applyBlock: (chain: ReturnType<Editor['chain']>) => ReturnType<Editor['chain']>,\n ) {\n const editor = this._editor\n const context = this._getSlashCommandContext()\n if (!editor || !context) { return false }\n\n this._clearSlashCommandText()\n applyBlock(\n editor.chain().focus().setTextSelection({ from: context.lineFrom, to: context.lineTo }),\n ).run()\n return true\n }\n\n private _toggleBold() {\n if (this._applySlashInlineMark('bold')) {\n return\n }\n this._toggleToolbarInlineMark('bold')\n }\n\n private _toggleItalic() {\n if (this._applySlashInlineMark('italic')) {\n return\n }\n this._toggleToolbarInlineMark('italic')\n }\n\n private _toggleUnderline() {\n if (this._applySlashInlineMark('underline')) {\n return\n }\n this._toggleToolbarInlineMark('underline')\n }\n\n private _toggleStrike() {\n if (this._applySlashInlineMark('strike')) {\n return\n }\n this._toggleToolbarInlineMark('strike')\n }\n\n private _toggleCode() {\n if (this._applySlashInlineMark('code')) {\n return\n }\n this._toggleToolbarInlineMark('code')\n }\n\n private _setHeading(level: number) {\n if (this._applySlashLineBlock(chain => chain.setHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }))) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }).run())\n }\n\n private _setParagraph() {\n if (this._applySlashLineBlock(chain => chain.setParagraph())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().setParagraph().run())\n }\n\n private _toggleBulletList() {\n if (this._applySlashLineBlock(chain => chain.toggleBulletList())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleBulletList().run())\n }\n\n private _toggleOrderedList() {\n if (this._applySlashLineBlock(chain => chain.toggleOrderedList())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleOrderedList().run())\n }\n\n private _toggleTaskList() {\n if (this._applySlashLineBlock(chain => chain.toggleTaskList())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleTaskList().run())\n }\n\n private _toggleBlockquote() {\n if (this._applySlashLineBlock(chain => chain.toggleBlockquote())) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().toggleBlockquote().run())\n }\n\n private _setTextAlign(align: string) {\n if (this._applySlashLineBlock(chain => chain.setTextAlign(align as any))) {\n return\n }\n this._applyFormat(() => this._editor?.chain().focus().setTextAlign(align as any).run())\n }\n\n private _normalizeLinkUrl(url: string) {\n const trimmed = url.trim()\n if (!trimmed) { return '' }\n if (/^(https?:\\/\\/|mailto:|tel:|#|\\/)/i.test(trimmed)) {\n return trimmed\n }\n return `https://${trimmed}`\n }\n\n private _getLinkLabelFromRange(range: { from: number, to: number } | null) {\n const editor = this._editor\n if (!editor || !range || range.from >= range.to) {\n return ''\n }\n return editor.state.doc.textBetween(range.from, range.to, '')\n }\n\n private _getLinkTargetRange() {\n const editor = this._editor\n if (!editor) { return null }\n\n const { selection } = editor.state\n if (!selection.empty) {\n return { from: selection.from, to: selection.to }\n }\n\n if (editor.isActive('link')) {\n editor.chain().focus().extendMarkRange('link').run()\n return {\n from: editor.state.selection.from,\n to: editor.state.selection.to,\n }\n }\n\n const $from = editor.state.doc.resolve(selection.from)\n return {\n from: $from.start(),\n to: $from.end(),\n }\n }\n\n private _setLink(event: MouseEvent) {\n const editor = this._editor\n const wrapper = this.shadowRoot?.querySelector<HTMLElement>('.editor-wrapper')\n const trigger = event.currentTarget instanceof HTMLElement ? event.currentTarget : null\n if (!editor || !wrapper || !trigger) { return }\n\n const linkRange = this._getLinkTargetRange()\n this._linkSelection = linkRange\n\n const wrapperRect = wrapper.getBoundingClientRect()\n const triggerRect = trigger.getBoundingClientRect()\n const maxLeft = Math.max(12, wrapperRect.width - 332)\n const left = Math.min(Math.max(12, triggerRect.left - wrapperRect.left), maxLeft)\n const top = triggerRect.bottom - wrapperRect.top + 8\n const currentHref = String(editor.getAttributes('link').href || '')\n const currentLabel = this._getLinkLabelFromRange(linkRange)\n\n this._linkEditor = {\n x: left,\n y: top,\n visible: true,\n url: currentHref,\n label: currentLabel,\n }\n\n this.updateComplete.then(() => {\n const input = this.shadowRoot?.querySelector<HTMLInputElement>('.link-editor__input[data-field=\"url\"]')\n input?.focus()\n input?.select()\n })\n }\n\n private _closeLinkEditor() {\n this._linkEditor = { ...this._linkEditor, visible: false }\n }\n\n private _handleLinkEditorInput(event: Event) {\n const target = event.target as HTMLInputElement\n const field = target.dataset.field === 'label' ? 'label' : 'url'\n this._linkEditor = {\n ...this._linkEditor,\n [field]: target.value,\n }\n }\n\n private _applyLink() {\n const editor = this._editor\n const href = this._normalizeLinkUrl(this._linkEditor.url)\n const label = this._linkEditor.label.trim() || href\n if (!editor || !href) { return }\n\n this._clearSlashCommandText()\n\n const selection = this._linkSelection ?? this._getLinkTargetRange() ?? editor.state.selection\n const insertTo = selection.from + label.length\n\n editor\n .chain()\n .focus()\n .insertContentAt(\n { from: selection.from, to: selection.to },\n {\n type: 'text',\n text: label,\n marks: [{ type: 'link', attrs: { href } }],\n },\n )\n .setTextSelection({ from: insertTo, to: insertTo })\n .run()\n\n this._closeLinkEditor()\n }\n\n private _removeLink() {\n const editor = this._editor\n if (!editor) { return }\n\n const selection = this._linkSelection ?? editor.state.selection\n let chain = editor.chain().focus()\n if (selection.from !== selection.to) {\n chain = chain.setTextSelection(selection)\n }\n chain.extendMarkRange('link').unsetLink().run()\n this._closeLinkEditor()\n }\n\n private _handleLinkEditorKeydown(event: KeyboardEvent) {\n if (event.key === 'Enter') {\n event.preventDefault()\n this._applyLink()\n return\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n this._closeLinkEditor()\n }\n }\n\n private _insertTable(rows?: number, cols?: number) {\n this._editor?.chain().focus().insertTable({ rows: rows ?? this._tableRows, cols: cols ?? this._tableCols, withHeaderRow: true }).run()\n }\n\n private async _handleImageUpload(e: Event) {\n const input = e.target as HTMLInputElement\n const files = Array.from(input.files ?? [])\n if (!files.length) {\n input.value = ''\n return\n }\n\n this._clearSlashCommandText()\n let insertRange = this._pendingImageInsertPos !== null\n ? { from: this._pendingImageInsertPos, to: this._pendingImageInsertPos }\n : this._editor\n ? { from: this._editor.state.selection.from, to: this._editor.state.selection.to }\n : null\n this._pendingImageInsertPos = null\n\n for (const file of files) {\n try {\n const naturalWidth = await this._getImageNaturalWidth(file)\n const src = await this['upload-image'](file)\n const initialWidth = naturalWidth\n ? Math.min(naturalWidth, this._getImageMaxWidth())\n : this._getImageMaxWidth()\n if (!insertRange && this._editor) {\n insertRange = { from: this._editor.state.selection.from, to: this._editor.state.selection.to }\n }\n\n if (!insertRange) {\n continue\n }\n\n const nextInsertPos = this._insertImageAt(insertRange, {\n src,\n width: initialWidth,\n align: 'left',\n })\n insertRange = { from: nextInsertPos, to: nextInsertPos }\n }\n catch (err) {\n console.error('图片上传失败:', err)\n const error = err instanceof Error ? err : new Error('图片上传失败')\n this.dispatchEvent(new CustomEvent<QxsBlocksuiteEditorImageUploadErrorDetail>('image-upload-error', {\n detail: {\n file,\n error,\n },\n bubbles: true,\n composed: true,\n }))\n }\n }\n input.value = ''\n }\n\n private _triggerImageUpload() {\n this._clearSlashCommandText()\n const input = this.shadowRoot?.querySelector<HTMLInputElement>('.image-input')\n if (!input) { return }\n\n input.value = ''\n\n const pickerInput = input as HTMLInputElement & { showPicker?: () => void }\n if (typeof pickerInput.showPicker === 'function') {\n try {\n pickerInput.showPicker()\n return\n }\n catch {\n // Fall back to click() for browsers that reject showPicker in this context.\n }\n }\n\n input.click()\n }\n\n private _insertTableByClick(rows: number, cols: number) {\n this._clearSlashCommandText()\n this._tableRows = rows\n this._tableCols = cols\n this._insertTable(rows, cols)\n }\n\n private _showTableCellToolbar() {\n if (!this._editor?.isActive('table')) { return }\n const { state } = this._editor\n const { selection } = state\n const coords = this._editor.view.coordsAtPos(selection.from)\n const editorWrapper = this.shadowRoot?.querySelector<HTMLElement>('.editor-wrapper')\n if (!editorWrapper) { return }\n const wrapperRect = editorWrapper.getBoundingClientRect()\n\n const cellRow = this._getTableCellRow()\n const cellCol = this._getTableCellCol()\n const isTopRow = cellRow === 0\n const isLeftCol = cellCol === 0\n\n // Only show toolbar on top row or left column\n if (!isTopRow && !isLeftCol) { return }\n\n requestAnimationFrame(() => {\n this._tableCellToolbar = {\n x: coords.left - wrapperRect.left,\n y: coords.bottom - wrapperRect.top + 8,\n visible: true,\n cellRow,\n cellCol,\n }\n })\n }\n\n private _getTableCellRow(): number {\n if (!this._editor) { return 0 }\n const { selection } = this._editor.state\n const $pos = this._editor.state.doc.resolve(selection.from)\n for (let d = $pos.depth; d > 0; d--) {\n const node = $pos.node(d)\n if (node.type.name === 'tableCell') {\n return $pos.index(d - 1)\n }\n }\n return 0\n }\n\n private _getTableCellCol(): number {\n if (!this._editor) { return 0 }\n const { selection } = this._editor.state\n const $pos = this._editor.state.doc.resolve(selection.from)\n for (let d = $pos.depth; d > 0; d--) {\n const node = $pos.node(d)\n if (node.type.name === 'tableCell') {\n return $pos.index(d)\n }\n }\n return 0\n }\n\n private _hideTableCellToolbar() {\n requestAnimationFrame(() => {\n this._tableCellToolbar = { ...this._tableCellToolbar, visible: false }\n })\n }\n\n private _addTableRowAbove() {\n this._editor?.chain().focus().addRowBefore().run()\n this._hideTableCellToolbar()\n }\n\n private _addTableRowBelow() {\n this._editor?.chain().focus().addRowAfter().run()\n this._hideTableCellToolbar()\n }\n\n private _addTableColumnLeft() {\n this._editor?.chain().focus().addColumnBefore().run()\n this._hideTableCellToolbar()\n }\n\n private _addTableColumnRight() {\n this._editor?.chain().focus().addColumnAfter().run()\n this._hideTableCellToolbar()\n }\n\n private _deleteTableRow() {\n this._editor?.chain().focus().deleteRow().run()\n this._hideTableCellToolbar()\n }\n\n private _deleteTableColumn() {\n this._editor?.chain().focus().deleteColumn().run()\n this._hideTableCellToolbar()\n }\n\n private _deleteTable() {\n this._editor?.chain().focus().deleteTable().run()\n this._hideTableCellToolbar()\n }\n\n // Image Toolbar Methods\n private _showImageToolbar(pos: { x: number, y: number }) {\n requestAnimationFrame(() => {\n this._imageToolbar = { x: pos.x, y: pos.y, visible: true }\n })\n }\n\n private _hideImageToolbar() {\n requestAnimationFrame(() => {\n this._imageToolbar = { ...this._imageToolbar, visible: false }\n })\n }\n\n private _deleteImage() {\n const selectedImage = this._getSelectedImageNode()\n if (!selectedImage) { return }\n\n const { editor, pos, node } = selectedImage\n editor.view.dispatch(editor.state.tr.delete(pos, pos + node.nodeSize))\n this._selectedImage = null\n this._pendingImageInsertPos = null\n this._hideImageToolbar()\n }\n\n private _insertImageAfter() {\n const selectedImage = this._getSelectedImageNode()\n if (!selectedImage) {\n this._triggerImageUpload()\n return\n }\n\n this._pendingImageInsertPos = selectedImage.pos + selectedImage.node.nodeSize\n this._triggerImageUpload()\n }\n\n private _getSelectedImageNode() {\n const editor = this._editor\n const pos = this._selectedImage?.pos\n if (!editor || pos === undefined) { return null }\n\n const node = editor.state.doc.nodeAt(pos)\n if (!node || node.type.name !== 'image') { return null }\n\n return { editor, pos, node }\n }\n\n private _insertImageAt(pos: number | { from: number, to: number }, attrs: Record<string, unknown>) {\n const editor = this._editor\n if (!editor) { return 0 }\n\n const range = typeof pos === 'number'\n ? {\n from: Math.max(0, Math.min(pos, editor.state.doc.content.size)),\n to: Math.max(0, Math.min(pos, editor.state.doc.content.size)),\n }\n : {\n from: Math.max(0, Math.min(pos.from, editor.state.doc.content.size)),\n to: Math.max(0, Math.min(pos.to, editor.state.doc.content.size)),\n }\n const insertPos = range.from\n\n const chain = editor.chain().focus() as any\n\n if (typeof chain.insertContentAt === 'function') {\n let nextChain = chain.insertContentAt(range, { type: 'image', attrs })\n if (typeof nextChain?.setNodeSelection === 'function') {\n nextChain = nextChain.setNodeSelection(insertPos)\n }\n nextChain.run()\n\n const insertedNodeSize = editor.state.doc.nodeAt(insertPos)?.nodeSize ?? 1\n return insertPos + insertedNodeSize\n }\n\n if (typeof chain.setImage === 'function') {\n chain.setImage(attrs).run()\n return insertPos + 1\n }\n\n return insertPos\n }\n\n private _updateSelectedImageAttributes(attrs: Record<string, unknown>) {\n const selectedImage = this._getSelectedImageNode()\n if (!selectedImage) { return }\n\n const { editor, pos, node } = selectedImage\n editor.view.dispatch(editor.state.tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n ...attrs,\n }))\n }\n\n private _setImageWidth(width: number) {\n const nextWidth = Math.max(MIN_IMAGE_WIDTH, Math.min(this._getImageMaxWidth(), Math.round(width)))\n this._updateSelectedImageAttributes({ width: nextWidth })\n }\n\n private _handleImageWidthInput(e: Event) {\n const rawValue = (e.target as HTMLInputElement).value.trim()\n if (!rawValue) { return }\n\n const value = Number(rawValue)\n if (!Number.isFinite(value)) { return }\n this._setImageWidth(value)\n }\n\n private _setImageAlignLeft() {\n this._updateSelectedImageAttributes({ align: 'left' })\n }\n\n private _setImageAlignCenter() {\n this._updateSelectedImageAttributes({ align: 'center' })\n }\n\n private _setImageAlignRight() {\n this._updateSelectedImageAttributes({ align: 'right' })\n }\n\n private _getTextLabel(): string {\n const editor = this._editor\n if (!editor) { return '正文' }\n if (editor.isActive('heading', { level: 1 })) { return '标题 1' }\n if (editor.isActive('heading', { level: 2 })) { return '标题 2' }\n if (editor.isActive('heading', { level: 3 })) { return '标题 3' }\n return '正文'\n }\n\n private _getAlignLabel(): string {\n const editor = this._editor\n if (!editor) { return '对齐' }\n if (editor.isActive({ textAlign: 'center' })) { return '居中' }\n if (editor.isActive({ textAlign: 'right' })) { return '右对齐' }\n return '左对齐'\n }\n\n private _renderImageControls() {\n const selectedImage = this._selectedImage\n if (!selectedImage) { return '' }\n\n return html`\n <button class=\"bubble-btn danger\" title=\"删除图片\" @click=${this._deleteImage}>\n <svg viewBox=\"0 0 24 24\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>\n </button>\n <button class=\"bubble-btn\" title=\"添加图片\" @click=${this._insertImageAfter}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>\n </button>\n <div class=\"bubble-divider\"></div>\n <span class=\"image-control-label\">对齐</span>\n <button class=\"bubble-btn ${selectedImage.align === 'left' ? 'is-active' : ''}\" title=\"左对齐\" @click=${this._setImageAlignLeft}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"15\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"18\" y2=\"18\"/></svg>\n </button>\n <button class=\"bubble-btn ${selectedImage.align === 'center' ? 'is-active' : ''}\" title=\"居中\" @click=${this._setImageAlignCenter}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/></svg>\n </button>\n <button class=\"bubble-btn ${selectedImage.align === 'right' ? 'is-active' : ''}\" title=\"右对齐\" @click=${this._setImageAlignRight}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"6\" y1=\"18\" x2=\"21\" y2=\"18\"/></svg>\n </button>\n <div class=\"image-size-control\">\n <span class=\"image-size-label\">宽度</span>\n <input\n class=\"image-size-range\"\n type=\"number\"\n min=\"${MIN_IMAGE_WIDTH}\"\n max=\"${this._getImageMaxWidth()}\"\n .value=${String(selectedImage.width)}\n @input=${this._handleImageWidthInput}\n />\n </div>\n `\n }\n\n private _joinToolbarGroups(groups: unknown[]) {\n return groups.flatMap((group, index) => index === 0\n ? [group]\n : [html`<div class=\"bubble-divider\"></div>`, group])\n }\n\n private _renderFormatToolbarGroup(editor: Editor | null) {\n return html`\n ${this._renderToolbarButton('bold', {\n title: '加粗',\n active: editor?.isActive('bold'),\n onClick: this._toggleBold,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/></svg>`,\n })}\n ${this._renderToolbarButton('italic', {\n title: '斜体',\n active: editor?.isActive('italic'),\n onClick: this._toggleItalic,\n icon: html`<svg viewBox=\"0 0 24 24\"><line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/></svg>`,\n })}\n ${this._renderToolbarButton('underline', {\n title: '下划线',\n active: editor?.isActive('underline'),\n onClick: this._toggleUnderline,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/></svg>`,\n })}\n ${this._renderToolbarButton('strike', {\n title: '删除线',\n active: editor?.isActive('strike'),\n onClick: this._toggleStrike,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M17.3 4.9c-2.3-.6-4.4-1-6.2-.9-2.7 0-5.3.7-5.3 3.6 0 1.5 1.8 3.3 5.3 3.9h.2m8.2 3.2c.3.4.4.8.4 1.3 0 2.9-2.7 3.6-6.2 3.6-2.3 0-4.4-.3-6.2-.9M4 12h16\"/></svg>`,\n })}\n `\n }\n\n private _renderHeadingToolbarGroup(editor: Editor | null) {\n return html`\n <div class=\"bubble-dropdown\">\n <button class=\"bubble-dropdown-btn\">\n ${this._getTextLabel()}\n <svg viewBox=\"0 0 24 24\"><polyline points=\"6 9 12 15 18 9\"/></svg>\n </button>\n <div class=\"bubble-dropdown-menu\">\n <button class=\"bubble-dropdown-item ${!editor?.isActive('heading') ? 'is-active' : ''}\" @click=${this._setParagraph}>正文</button>\n <button class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 1 }) ? 'is-active' : ''}\" @click=${() => this._setHeading(1)}>标题 1</button>\n <button class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 2 }) ? 'is-active' : ''}\" @click=${() => this._setHeading(2)}>标题 2</button>\n <button class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 3 }) ? 'is-active' : ''}\" @click=${() => this._setHeading(3)}>标题 3</button>\n </div>\n </div>\n `\n }\n\n private _renderAlignToolbarGroup(editor: Editor | null) {\n return html`\n <div class=\"bubble-dropdown\">\n <button class=\"bubble-dropdown-btn\">\n ${this._getAlignLabel()}\n <svg viewBox=\"0 0 24 24\"><polyline points=\"6 9 12 15 18 9\"/></svg>\n </button>\n <div class=\"bubble-dropdown-menu\">\n <button class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'left' }) ? 'is-active' : ''}\" @click=${() => this._setTextAlign('left')}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"15\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"18\" y2=\"18\"/></svg>\n 左对齐\n </button>\n <button class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'center' }) ? 'is-active' : ''}\" @click=${() => this._setTextAlign('center')}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/></svg>\n 居中\n </button>\n <button class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'right' }) ? 'is-active' : ''}\" @click=${() => this._setTextAlign('right')}>\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"6\" y1=\"18\" x2=\"21\" y2=\"18\"/></svg>\n 右对齐\n </button>\n </div>\n </div>\n `\n }\n\n private _renderCodeLinkImageToolbarGroup(editor: Editor | null) {\n return html`\n ${this._hasToolbarItem('code')\n ? this._renderToolbarButton('code', {\n title: '行内代码',\n active: editor?.isActive('code'),\n onClick: this._toggleCode,\n icon: html`<svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>`,\n })\n : ''}\n ${this._hasToolbarItem('link')\n ? this._renderToolbarButton('link', {\n title: '链接',\n active: editor?.isActive('link'),\n onClick: this._setLink,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>`,\n })\n : ''}\n ${this._hasToolbarItem('image')\n ? this._renderToolbarButton('image', {\n title: '图片',\n onClick: this._triggerImageUpload,\n icon: html`<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>`,\n })\n : ''}\n `\n }\n\n private _renderCodeToolbarButton(editor: Editor | null) {\n return this._renderToolbarButton('code', {\n title: '行内代码',\n active: editor?.isActive('code'),\n onClick: this._toggleCode,\n icon: html`<svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>`,\n })\n }\n\n private _renderLinkToolbarButton(editor: Editor | null) {\n return this._renderToolbarButton('link', {\n title: '链接',\n active: editor?.isActive('link'),\n onClick: this._setLink,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>`,\n })\n }\n\n private _renderImageToolbarButton() {\n return this._renderToolbarButton('image', {\n title: '图片',\n onClick: this._triggerImageUpload,\n icon: html`<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>`,\n })\n }\n\n private _renderListToolbarGroup(editor: Editor | null) {\n return html`\n ${this._renderToolbarButton('bulletList', {\n title: '无序列表',\n active: editor?.isActive('bulletList'),\n onClick: this._toggleBulletList,\n icon: html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"9\" y1=\"6\" x2=\"20\" y2=\"6\"/>\n <line x1=\"9\" y1=\"12\" x2=\"20\" y2=\"12\"/>\n <line x1=\"9\" y1=\"18\" x2=\"20\" y2=\"18\"/>\n <circle cx=\"4\" cy=\"6\" r=\"0.5\" fill=\"currentColor\" stroke=\"none\"/>\n <circle cx=\"4\" cy=\"12\" r=\"0.5\" fill=\"currentColor\" stroke=\"none\"/>\n <circle cx=\"4\" cy=\"18\" r=\"0.5\" fill=\"currentColor\" stroke=\"none\"/>\n </svg>`,\n })}\n ${this._renderToolbarButton('orderedList', {\n title: '有序列表',\n active: editor?.isActive('orderedList'),\n onClick: this._toggleOrderedList,\n icon: html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/>\n <line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/>\n <line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/>\n <path d=\"M4 6h1v4\"/>\n <path d=\"M4 10h2\"/>\n <path d=\"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1.5\"/>\n </svg>`,\n })}\n ${this._renderToolbarButton('taskList', {\n title: '待办列表',\n active: editor?.isActive('taskList'),\n onClick: this._toggleTaskList,\n icon: html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"3\" y=\"5\" width=\"4\" height=\"4\" rx=\"1\"/>\n <polyline points=\"4 7 5 8 6.5 6.5\"/>\n <line x1=\"10\" y1=\"7\" x2=\"21\" y2=\"7\"/>\n <rect x=\"3\" y=\"15\" width=\"4\" height=\"4\" rx=\"1\"/>\n <line x1=\"10\" y1=\"17\" x2=\"21\" y2=\"17\"/>\n </svg>`,\n })}\n `\n }\n\n private _renderBlockquoteToolbarGroup(editor: Editor | null) {\n return html`\n ${this._renderToolbarButton('blockquote', {\n title: '引用',\n active: editor?.isActive('blockquote'),\n onClick: this._toggleBlockquote,\n icon: html`<svg viewBox=\"0 0 24 24\"><path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V21z\"/><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\"/></svg>`,\n })}\n `\n }\n\n private _renderTableToolbarGroup() {\n const label = this._getHeaderToolbarLabel('table')\n return html`\n <div\n class=\"bubble-dropdown ${this._tableDropdownOpen ? 'is-open' : ''}\"\n @mouseenter=${() => {\n this._tableDropdownOpen = true\n this._hoverRow = 0\n this._hoverCol = 0\n }}\n @mouseleave=${() => this._tableDropdownOpen = false}\n >\n <button class=\"bubble-dropdown-btn ${label ? 'has-label' : ''}\" title=\"表格\">\n <svg viewBox=\"0 0 24 24\" style=\"width:18px;height:18px;stroke:currentColor;stroke-width:2;fill:none;\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/></svg>\n ${label ? html`<span class=\"bubble-dropdown-btn__label\">${label}</span>` : null}\n </button>\n <div class=\"bubble-dropdown-menu\">\n <div class=\"table-grid-preview\">\n ${this._renderTableGrid()}\n </div>\n <div class=\"table-size-hint\">\n <span>${this._hoverRow > 0 ? `${this._hoverRow} × ${this._hoverCol}` : `${this._tableRows} × ${this._tableCols}`}</span>\n </div>\n </div>\n </div>\n `\n }\n\n private _getToolbarMergeKey(item: EditorToolbarItem): string {\n if (item === 'code' || item === 'link' || item === 'image') {\n return 'code-link-image'\n }\n\n return item\n }\n\n private _renderToolbarItemByKey(editor: Editor | null, item: EditorToolbarItem): unknown {\n switch (item) {\n case 'format':\n return this._renderFormatToolbarGroup(editor)\n case 'heading':\n return this._renderHeadingToolbarGroup(editor)\n case 'align':\n return this._renderAlignToolbarGroup(editor)\n case 'code':\n return this._renderCodeToolbarButton(editor)\n case 'link':\n return this._renderLinkToolbarButton(editor)\n case 'image':\n return this._renderImageToolbarButton()\n case 'list':\n return this._renderListToolbarGroup(editor)\n case 'blockquote':\n return this._renderBlockquoteToolbarGroup(editor)\n case 'table':\n return this._renderTableToolbarGroup()\n default:\n return null\n }\n }\n\n private _renderTextToolbar(editor: Editor | null) {\n const groups: unknown[] = []\n\n let currentMergeKey = ''\n let currentGroup: unknown[] = []\n\n const flushGroup = () => {\n if (currentGroup.length) {\n groups.push([...currentGroup])\n currentGroup = []\n }\n }\n\n for (const item of this._toolbarItemsValue) {\n const rendered = this._renderToolbarItemByKey(editor, item)\n if (!rendered) {\n continue\n }\n\n const mergeKey = this._getToolbarMergeKey(item)\n if (currentGroup.length && mergeKey !== currentMergeKey) {\n flushGroup()\n }\n\n currentMergeKey = mergeKey\n currentGroup.push(rendered)\n }\n\n flushGroup()\n\n return this._joinToolbarGroups(groups)\n }\n\n private _updateBubbleMenuPosition() {\n if (this._toolbarModeValue !== 'slash') { return }\n requestAnimationFrame(() => {\n const bubbleMenu = this.shadowRoot?.querySelector<HTMLElement>('.bubble-menu')\n const proseMirror = this.shadowRoot?.querySelector<HTMLElement>('.ProseMirror')\n const editorWrapper = this.shadowRoot?.querySelector<HTMLElement>('.editor-wrapper')\n if (!bubbleMenu || !proseMirror || !editorWrapper) { return }\n\n const editor = this._editor\n const isInTable = editor?.isActive('table') ?? false\n const { selection } = editor?.state ?? { selection: null }\n\n // 如果选中了表格节点(而不只是单元格内的文字),隐藏菜单\n if (isInTable && selection && !selection.empty && editor) {\n const { from, to } = selection\n const $from = editor.state.doc.resolve(from)\n const $to = editor.state.doc.resolve(to)\n // 检查选区起点和终点之间是否有表格节点\n let hasTableInSelection = false\n for (let d = $from.depth; d >= 0; d--) {\n if ($from.node(d).type.name === 'table') {\n hasTableInSelection = true\n break\n }\n }\n // 如果选区起点在表格外但终点在表格内,或者选区跨越了表格\n const fromAncestor = $from.node($from.depth)\n const toAncestor = $to.node($to.depth)\n if (fromAncestor.type.name === 'table' || toAncestor.type.name === 'table') {\n hasTableInSelection = true\n }\n if (hasTableInSelection) {\n bubbleMenu.style.opacity = '0'\n bubbleMenu.style.visibility = 'hidden'\n return\n }\n }\n\n // 如果有选中文字,显示菜单\n if (selection && !selection.empty) {\n // continue to show menu\n }\n else if (!selection || (selection.empty && !this._hasSlashCommand)) {\n bubbleMenu.style.opacity = '0'\n bubbleMenu.style.visibility = 'hidden'\n return\n }\n\n const wrapperRect = editorWrapper.getBoundingClientRect()\n const menuRect = bubbleMenu.getBoundingClientRect()\n\n const { from } = selection!\n const coords = this._editor?.view.coordsAtPos(from)\n if (!coords) { return }\n\n let left = coords.left - wrapperRect.left\n let top = coords.top - wrapperRect.top - 40\n\n if (left + menuRect.width > wrapperRect.width) {\n left = wrapperRect.width - menuRect.width - 8\n }\n if (left < 0) {\n left = 8\n }\n\n if (top < 0) {\n top = coords.bottom - wrapperRect.top + 8\n }\n\n bubbleMenu.style.left = `${left}px`\n bubbleMenu.style.top = `${top}px`\n bubbleMenu.style.opacity = '1'\n bubbleMenu.style.visibility = 'visible'\n })\n }\n\n render() {\n const editor = this._editor\n const headerTemplate = !this._previewValue && this._toolbarModeValue === 'header'\n ? html`\n <div class=\"editor-header ${this._isHeaderVisible() ? 'is-visible' : ''}\">\n <div class=\"editor-header__inner\" @mousedown=${this._handleHeaderToolbarMouseDown}>\n ${this._selectedImage\n ? this._renderImageControls()\n : this._renderTextToolbar(editor)}\n </div>\n </div>\n `\n : null\n const shouldShowCharacterCount = this._showCharacterCountValue && !this._previewValue\n\n return html`\n <div\n class=\"editor-wrapper ${!editor ? 'loading' : ''} ${this._previewValue ? 'preview' : ''} ${this._toolbarPositionValue === 'bottom' ? 'toolbar-bottom' : ''}\"\n style=${this._wrapperStyleValue}\n @mousedown=${this._handleWrapperMouseDown}\n @focusin=${this._handleWrapperFocusIn}\n @focusout=${this._handleWrapperFocusOut}\n >\n ${!editor\n ? html`\n <div class=\"loading-placeholder\">\n <div class=\"loading-spinner\"></div>\n <span>编辑器加载中...</span>\n </div>\n `\n : ''}\n <input\n type=\"file\"\n accept=\"image/*\"\n multiple\n class=\"image-input\"\n @change=${this._handleImageUpload}\n />\n\n ${this._toolbarPositionValue === 'top' ? headerTemplate : null}\n\n <!-- Bubble Menu (悬浮操作栏) -->\n ${!this._previewValue && this._toolbarModeValue === 'slash'\n ? html`\n <div class=\"bubble-menu\">\n ${this._renderTextToolbar(editor)}\n </div>\n `\n : ''}\n\n <div class=\"editor-content\" data-empty-hint=${this._resolvedPlaceholder}></div>\n\n ${this._toolbarPositionValue === 'bottom' ? headerTemplate : null}\n\n ${shouldShowCharacterCount\n ? html`<div class=\"editor-footer\">${this._getEditorCharacterCount()} 字符</div>`\n : null}\n\n ${this._linkEditor.visible\n ? html`\n <div\n class=\"link-editor\"\n style=\"left: ${this._linkEditor.x}px; top: ${this._linkEditor.y}px;\"\n @mousedown=${(event: MouseEvent) => event.stopPropagation()}\n @click=${(event: MouseEvent) => event.stopPropagation()}\n >\n <div class=\"link-editor__field\">\n <span class=\"link-editor__label\">链接地址</span>\n <input\n class=\"link-editor__input\"\n data-field=\"url\"\n type=\"text\"\n placeholder=\"输入或粘贴链接\"\n .value=${this._linkEditor.url}\n @input=${this._handleLinkEditorInput}\n @keydown=${this._handleLinkEditorKeydown}\n />\n </div>\n <div class=\"link-editor__field\">\n <span class=\"link-editor__label\">链接名字</span>\n <input\n class=\"link-editor__input\"\n data-field=\"label\"\n type=\"text\"\n placeholder=\"输入展示名称\"\n .value=${this._linkEditor.label}\n @input=${this._handleLinkEditorInput}\n @keydown=${this._handleLinkEditorKeydown}\n />\n </div>\n <div class=\"link-editor__actions\">\n <button class=\"link-editor__action primary\" title=\"应用链接\" @click=${this._applyLink}>应用</button>\n <button class=\"link-editor__action\" title=\"取消链接编辑\" @click=${this._closeLinkEditor}>取消</button>\n ${(editor?.isActive('link') || this._linkEditor.url)\n ? html`<button class=\"link-editor__action danger\" title=\"移除链接\" @click=${this._removeLink}>移除</button>`\n : ''}\n </div>\n </div>\n `\n : ''}\n\n <!-- Table Cell Toolbar -->\n ${this._tableCellToolbar.visible && editor?.isActive('table')\n ? html`\n <div\n class=\"table-cell-toolbar\"\n style=\"left: ${this._tableCellToolbar.x}px; top: ${this._tableCellToolbar.y}px;\"\n @mousedown=${(e: Event) => e.preventDefault()}\n >\n ${this._tableCellToolbar.cellRow === 0\n ? html`\n <button class=\"table-cell-toolbar-btn\" title=\"上方添加行\" @click=${this._addTableRowAbove}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"7\"/><line x1=\"10\" y1=\"5\" x2=\"14\" y2=\"5\"/></svg>\n </button>\n <button class=\"table-cell-toolbar-btn\" title=\"下方添加行\" @click=${this._addTableRowBelow}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"17\"/><line x1=\"10\" y1=\"19\" x2=\"14\" y2=\"19\"/></svg>\n </button>\n <button class=\"table-cell-toolbar-btn danger\" title=\"删除行\" @click=${this._deleteTableRow}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"1\"/><line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"14\"/><line x1=\"15\" y1=\"10\" x2=\"15\" y2=\"14\"/></svg>\n </button>\n `\n : ''}\n ${this._tableCellToolbar.cellCol === 0\n ? html`\n ${this._tableCellToolbar.cellRow !== 0 ? html`<div style=\"width:1px;height:20px;background:#e3e3e3;margin:0 4px;\"></div>` : ''}\n <button class=\"table-cell-toolbar-btn\" title=\"左侧添加列\" @click=${this._addTableColumnLeft}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"8\" y=\"4\" width=\"8\" height=\"16\" rx=\"1\"/><line x1=\"3\" y1=\"12\" x2=\"7\" y2=\"12\"/><line x1=\"5\" y1=\"10\" x2=\"5\" y2=\"14\"/></svg>\n </button>\n <button class=\"table-cell-toolbar-btn\" title=\"右侧添加列\" @click=${this._addTableColumnRight}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"8\" y=\"4\" width=\"8\" height=\"16\" rx=\"1\"/><line x1=\"21\" y1=\"12\" x2=\"17\" y2=\"12\"/><line x1=\"19\" y1=\"10\" x2=\"19\" y2=\"14\"/></svg>\n </button>\n <button class=\"table-cell-toolbar-btn danger\" title=\"删除列\" @click=${this._deleteTableColumn}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><rect x=\"8\" y=\"4\" width=\"8\" height=\"16\" rx=\"1\"/><line x1=\"10\" y1=\"9\" x2=\"14\" y2=\"9\"/><line x1=\"10\" y1=\"15\" x2=\"14\" y2=\"15\"/></svg>\n </button>\n `\n : ''}\n ${this._tableCellToolbar.cellRow === 0 && this._tableCellToolbar.cellCol === 0\n ? html`\n <div style=\"width:1px;height:20px;background:#e3e3e3;margin:0 4px;\"></div>\n <button class=\"table-cell-toolbar-btn danger\" title=\"删除表格\" @click=${this._deleteTable}>\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>\n </button>\n `\n : ''}\n </div>\n `\n : ''}\n\n <!-- Image Toolbar -->\n ${this._toolbarModeValue === 'slash' && this._imageToolbar.visible\n ? html`\n <div\n class=\"image-toolbar\"\n style=\"left: ${this._imageToolbar.x}px; top: ${this._imageToolbar.y}px;\"\n @mousedown=${(e: Event) => e.preventDefault()}\n >\n ${this._renderImageControls()}\n </div>\n `\n : ''}\n </div>\n `\n }\n\n private _renderTableGrid() {\n const cells = []\n for (let i = 0; i < 100; i++) {\n const row = Math.floor(i / 10) + 1\n const col = (i % 10) + 1\n const isHighlight = this._hoverRow > 0 && row <= this._hoverRow && col <= this._hoverCol\n cells.push(html`\n <div\n class=\"table-cell ${isHighlight ? 'selected' : ''}\"\n @click=${() => {\n this._insertTableByClick(row, col)\n this._tableDropdownOpen = false\n }}\n @mouseenter=${() => {\n this._hoverRow = row\n this._hoverCol = col\n }}\n @mouseleave=${() => {\n this._hoverRow = 0\n this._hoverCol = 0\n }}\n ></div>\n `)\n }\n return cells\n }\n}\n\nexport function register() {}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qxs-blocksuite-editor': QxsBlocksuiteEditor\n }\n}\n"],"names":["DEFAULT_IMAGE_WIDTH","MIN_IMAGE_WIDTH","DEFAULT_HEADER_PLACEHOLDER","DEFAULT_SLASH_PLACEHOLDER","DEFAULT_MIN_HEIGHT","DEFAULT_HEADER_TOOLBAR_LABELS","HEADER_TOOLBAR_LABEL_KEYS","TaskList","TiptapNode","HTMLAttributes","mergeAttributes","commands","TaskItem","element","attributes","checked","ExtendedListItem","ListItem","ExtendedImage","Image","attr","value","width","style","QxsBlocksuiteEditor","LitElement","file","resolve","reject","reader","e","shadow","styleEl","overflowY","parseEditorToolbarItems","SIMPLE_EDITOR_TOOLBAR","DEFAULT_EDITOR_TOOLBAR","item","source","parsed","error","labels","key","message","options","label","className","html","transform","transformIncomingContentByFormat","EMPTY_EDITOR_HTML","transformOutgoingContentByFormat","el","useModel","modelValue","contentValue","initialContent","extensions","Document","Paragraph","Text","Bold","Italic","Underline","Strike","Code","Heading","BulletList","OrderedList","Blockquote","HorizontalRule","History","Link","TextAlign","Table","TableRow","TableCell","TableHeader","Placeholder","Editor","event","target","editor","taskItem","basePos","searchFrom","searchTo","taskItemPos","node","pos","snapshot","editorContent","editorWrapper","handleEditorClick","nextTarget","wrapper","selection","availableWidth","objectUrl","image","naturalWidth","align","wrapperRect","coords","x","y","from","to","$from","textBefore","matched","slashText","changed","nextValue","newContent","editorDom","text","command","range","force","state","currentLineStart","chain","type","mode","charBefore","markType","storedMarks","mark","startPos","lineStart","cursorPos","lineRange","context","applyBlock","level","url","trimmed","trigger","linkRange","triggerRect","maxLeft","left","top","currentHref","currentLabel","input","field","href","insertTo","rows","cols","files","insertRange","src","initialWidth","nextInsertPos","err","pickerInput","cellRow","cellCol","$pos","d","selectedImage","attrs","insertPos","nextChain","insertedNodeSize","nextWidth","rawValue","groups","group","index","currentMergeKey","currentGroup","flushGroup","rendered","mergeKey","bubbleMenu","proseMirror","isInTable","$to","hasTableInSelection","fromAncestor","toAncestor","menuRect","headerTemplate","shouldShowCharacterCount","cells","i","row","col","isHighlight","css","__decorateClass","property","safeCustomElement"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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"}
|