@qxs-bns/components-wc 0.0.26 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/es/editor/blocksuite-editor.mjs +312 -43
  2. package/es/editor/blocksuite-editor.mjs.map +1 -1
  3. package/es/entry-subject.mjs +1 -1
  4. package/es/index.mjs +1 -1
  5. package/es/subject/blank-fill.mjs +16 -13
  6. package/es/subject/blank-fill.mjs.map +1 -1
  7. package/es/subject/draft.mjs +2 -0
  8. package/es/subject/draft.mjs.map +1 -0
  9. package/es/subject/page-end.mjs +3 -3
  10. package/es/subject/page-end.mjs.map +1 -1
  11. package/es/subject/pagination.mjs +2 -0
  12. package/es/subject/pagination.mjs.map +1 -0
  13. package/es/subject/runtime.mjs +2 -0
  14. package/es/subject/runtime.mjs.map +1 -0
  15. package/es/subject/scale.mjs +53 -33
  16. package/es/subject/scale.mjs.map +1 -1
  17. package/es/subject/single.mjs +69 -42
  18. package/es/subject/single.mjs.map +1 -1
  19. package/es/subject/sort-controller.mjs +2 -0
  20. package/es/subject/sort-controller.mjs.map +1 -0
  21. package/es/subject/sortable.mjs +30 -0
  22. package/es/subject/sortable.mjs.map +1 -0
  23. package/es/subject/sorting-card.mjs +52 -0
  24. package/es/subject/sorting-card.mjs.map +1 -0
  25. package/es/subject/text-fill.mjs +15 -12
  26. package/es/subject/text-fill.mjs.map +1 -1
  27. package/es/subject/types.mjs +1 -1
  28. package/es/subject/types.mjs.map +1 -1
  29. package/lib/editor/blocksuite-editor.cjs +304 -35
  30. package/lib/editor/blocksuite-editor.cjs.map +1 -1
  31. package/lib/entry-subject.cjs +1 -1
  32. package/lib/index.cjs +1 -1
  33. package/lib/subject/blank-fill.cjs +16 -13
  34. package/lib/subject/blank-fill.cjs.map +1 -1
  35. package/lib/subject/draft.cjs +2 -0
  36. package/lib/subject/draft.cjs.map +1 -0
  37. package/lib/subject/page-end.cjs +3 -3
  38. package/lib/subject/page-end.cjs.map +1 -1
  39. package/lib/subject/pagination.cjs +2 -0
  40. package/lib/subject/pagination.cjs.map +1 -0
  41. package/lib/subject/runtime.cjs +2 -0
  42. package/lib/subject/runtime.cjs.map +1 -0
  43. package/lib/subject/scale.cjs +48 -28
  44. package/lib/subject/scale.cjs.map +1 -1
  45. package/lib/subject/single.cjs +69 -42
  46. package/lib/subject/single.cjs.map +1 -1
  47. package/lib/subject/sort-controller.cjs +2 -0
  48. package/lib/subject/sort-controller.cjs.map +1 -0
  49. package/lib/subject/sortable.cjs +30 -0
  50. package/lib/subject/sortable.cjs.map +1 -0
  51. package/lib/subject/sorting-card.cjs +52 -0
  52. package/lib/subject/sorting-card.cjs.map +1 -0
  53. package/lib/subject/text-fill.cjs +15 -12
  54. package/lib/subject/text-fill.cjs.map +1 -1
  55. package/lib/subject/types.cjs +1 -1
  56. package/lib/subject/types.cjs.map +1 -1
  57. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"blocksuite-editor.mjs","sources":["../../../../packages/components-wc/src/editor/blocksuite-editor.ts"],"sourcesContent":["import { Editor, Extension } 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 { property, state } from 'lit/decorators.js'\nimport { safeCustomElement } from '../base/define'\n\n@safeCustomElement('qxs-blocksuite-editor')\nexport class QxsBlocksuiteEditor extends LitElement {\n static styles = css`\n :host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, sans-serif;\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: 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 }\n\n .editor-content {\n padding: 12px 16px;\n min-height: 80px;\n cursor: text;\n }\n\n .editor-content:empty::before {\n content: '输入 / 唤出快捷命令';\n color: #c0c0c0;\n pointer-events: none;\n display: block;\n padding-top: 28px;\n text-align: center;\n }\n\n .editor-content .ProseMirror:empty {\n min-height: 80px;\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 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 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 }\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: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 svg {\n width: 16px;\n height: 16px;\n stroke: currentColor;\n stroke-width: 2;\n fill: none;\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: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-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 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 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 = '输入 / 唤出快捷命令'\n\n @property({ type: String, attribute: 'use-model' })\n 'use-model' = 'false'\n\n @property({ type: String, attribute: 'readonly' })\n readonly = 'false'\n\n @property({ type: String, attribute: 'preview' })\n preview = 'false'\n\n @property({ type: String, attribute: 'custom-styles' })\n 'custom-styles' = ''\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 @property({ type: Object, attribute: 'upload-image' })\n 'upload-image': (file: File) => Promise<string> = 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 @state() 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 _imageMoreMenuVisible = false\n private _hasSlashCommand = false\n private _isUpdating = 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._pendingContent ?? modelValue) || '<p></p>'\n : (this._pendingContent ?? contentValue) || '<p></p>'\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 ListItem,\n Blockquote,\n HorizontalRule,\n History,\n Image.configure({\n inline: false,\n allowBase64: true,\n }),\n Link.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.placeholder,\n }),\n Extension.create({\n name: 'clearMarksOnEnter',\n addKeyboardShortcuts() {\n return {\n Enter: () => {\n this.editor.chain().focus().unsetAllMarks().clearNodes().run()\n return false\n },\n }\n },\n }),\n ]\n\n this._editor = new Editor({\n element: el,\n extensions,\n editable: !this._readonlyValue,\n content: initialContent,\n })\n\n this._pendingContent = null\n\n this._editor.on('selectionUpdate', () => {\n this._updateBubbleMenuPosition()\n if (this._editor?.isActive('table')) {\n this._showTableCellToolbar()\n }\n else {\n this._hideTableCellToolbar()\n }\n // Image selection detection\n const editor = this._editor\n if (editor) {\n const { selection } = editor.state\n const { $from } = selection\n const node = $from.node($from.depth)\n if (node.type.name === 'image') {\n const coords = editor.view.coordsAtPos($from.start())\n const wrapperRect = this.shadowRoot?.querySelector('.editor-wrapper')?.getBoundingClientRect()\n if (wrapperRect) {\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 else {\n this._hideImageToolbar()\n }\n }\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._setupTableEdgeDetection()\n })\n\n this._editor.on('update', () => {\n this._emitContentChange()\n })\n }\n\n private _tableEdgeDetectionSetup = false\n\n private _emitContentChange() {\n if (!this._editor) { return }\n const html = this._editor.getHTML()\n\n this.dispatchEvent(new CustomEvent('content-change', {\n detail: html,\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 = () => {\n this._editor?.chain().focus().run()\n }\n\n editorContent.addEventListener('click', handleEditorClick)\n editorWrapper?.addEventListener('click', handleEditorClick)\n }\n\n private _checkSlashCommand() {\n if (!this._editor) { return }\n const { selection } = this._editor.state\n const textBefore = this._editor.state.doc.textBetween(\n Math.max(0, selection.from - 10),\n selection.from,\n ' ',\n )\n this._hasSlashCommand = textBefore.endsWith('/')\n }\n\n firstUpdated() {\n this._injectCustomStyles()\n this._initEditor()\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 (changed.has('content') || (changed.has('model-value') && this._useModelValue)) {\n const newContent = this._useModelValue ? this['model-value'] : this.content\n if (newContent !== this._editor.getHTML()) {\n this._editor.commands.setContent(newContent || '<p></p>')\n }\n }\n if (changed.has('readonly')) {\n this._editor.setEditable(!this._readonlyValue)\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 this._editor?.destroy()\n this._editor = null\n }\n\n getContent(): string {\n return this._editor?.getHTML() ?? ''\n }\n\n forceUpdate(): void {\n this.requestUpdate()\n if (this._editor) {\n const newContent = this._useModelValue ? this['model-value'] : this.content\n if (newContent !== this._editor.getHTML()) {\n this._editor.commands.setContent(newContent || '<p></p>')\n }\n }\n }\n\n private _applyFormat(command: () => void) {\n if (this._hasSlashCommand && this._editor) {\n const { selection } = this._editor.state\n this._editor.chain().focus().deleteRange({ from: selection.from - 1, to: selection.from }).run()\n this._hasSlashCommand = false\n }\n command()\n }\n\n private _toggleBold() {\n this._applyFormat(() => this._editor?.chain().focus().toggleBold().run())\n }\n\n private _toggleItalic() {\n this._applyFormat(() => this._editor?.chain().focus().toggleItalic().run())\n }\n\n private _toggleUnderline() {\n this._applyFormat(() => this._editor?.chain().focus().toggleUnderline().run())\n }\n\n private _toggleStrike() {\n this._applyFormat(() => this._editor?.chain().focus().toggleStrike().run())\n }\n\n private _toggleCode() {\n this._applyFormat(() => this._editor?.chain().focus().toggleCode().run())\n }\n\n private _setHeading(level: number) {\n this._applyFormat(() => this._editor?.chain().focus().toggleHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }).run())\n }\n\n private _setParagraph() {\n this._applyFormat(() => this._editor?.chain().focus().setParagraph().run())\n }\n\n private _toggleBulletList() {\n this._applyFormat(() => this._editor?.chain().focus().toggleBulletList().run())\n }\n\n private _toggleOrderedList() {\n this._applyFormat(() => this._editor?.chain().focus().toggleOrderedList().run())\n }\n\n private _toggleBlockquote() {\n this._applyFormat(() => this._editor?.chain().focus().toggleBlockquote().run())\n }\n\n private _setTextAlign(align: string) {\n this._applyFormat(() => this._editor?.chain().focus().setTextAlign(align as any).run())\n }\n\n private _setLink() {\n // eslint-disable-next-line no-alert\n const url = window.prompt('请输入链接地址:')\n if (url) {\n this._applyFormat(() => this._editor?.chain().focus().setLink({ href: url }).run())\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 src = await this['upload-image'](file)\n this._editor?.chain().focus().setImage({ src }).run()\n }\n catch (err) {\n console.error('图片上传失败:', err)\n }\n }\n input.value = ''\n }\n\n private _triggerImageUpload() {\n const input = this.shadowRoot?.querySelector<HTMLInputElement>('.image-input')\n input?.click()\n }\n\n private _insertTableByClick(rows: number, cols: number) {\n if (this._hasSlashCommand && this._editor) {\n const { selection } = this._editor.state\n this._editor.chain().focus().deleteRange({ from: selection.from - 1, to: selection.from }).run()\n this._hasSlashCommand = false\n }\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 this._imageMoreMenuVisible = false\n })\n }\n\n private _hideImageToolbar() {\n requestAnimationFrame(() => {\n this._imageToolbar = { ...this._imageToolbar, visible: false }\n this._imageMoreMenuVisible = false\n })\n }\n\n private _toggleImageMoreMenu() {\n this._imageMoreMenuVisible = !this._imageMoreMenuVisible\n }\n\n private _deleteImage() {\n this._editor?.chain().focus().deleteNode('image').run()\n this._hideImageToolbar()\n }\n\n private _insertImageAfter() {\n this._triggerImageUpload()\n this._imageMoreMenuVisible = false\n }\n\n private _setImageAlignLeft() {\n const editor = this._editor\n if (editor) {\n const { selection } = editor.state\n const pos = selection.from\n editor.chain().focus().setNodeSelection(pos).run()\n const img = this.shadowRoot?.querySelector('.ProseMirror img.ProseMirror-selectednode') as HTMLElement\n if (img) {\n img.style.display = 'block'\n img.style.margin = '0 auto 0 0'\n }\n }\n this._imageMoreMenuVisible = false\n }\n\n private _setImageAlignCenter() {\n const editor = this._editor\n if (editor) {\n const { selection } = editor.state\n const pos = selection.from\n editor.chain().focus().setNodeSelection(pos).run()\n const img = this.shadowRoot?.querySelector('.ProseMirror img.ProseMirror-selectednode') as HTMLElement\n if (img) {\n img.style.display = 'block'\n img.style.margin = '0 auto'\n }\n }\n this._imageMoreMenuVisible = false\n }\n\n private _setImageAlignRight() {\n const editor = this._editor\n if (editor) {\n const { selection } = editor.state\n const pos = selection.from\n editor.chain().focus().setNodeSelection(pos).run()\n const img = this.shadowRoot?.querySelector('.ProseMirror img.ProseMirror-selectednode') as HTMLElement\n if (img) {\n img.style.display = 'block'\n img.style.margin = '0 0 0 auto'\n }\n }\n this._imageMoreMenuVisible = false\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 _updateBubbleMenuPosition() {\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\n return html`\n <div class=\"editor-wrapper ${!editor ? 'loading' : ''} ${this._previewValue ? 'preview' : ''}\">\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 <!-- Bubble Menu (悬浮操作栏) -->\n ${!this._previewValue\n ? html`\n <div class=\"bubble-menu\">\n <!-- 文本格式 -->\n <button\n class=\"bubble-btn ${editor?.isActive('bold') ? 'is-active' : ''}\"\n @click=${this._toggleBold}\n title=\"加粗\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('italic') ? 'is-active' : ''}\"\n @click=${this._toggleItalic}\n title=\"斜体\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('underline') ? 'is-active' : ''}\"\n @click=${this._toggleUnderline}\n title=\"下划线\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('strike') ? 'is-active' : ''}\"\n @click=${this._toggleStrike}\n title=\"删除线\"\n >\n <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 </button>\n\n <div class=\"bubble-divider\"></div>\n\n <!-- 文本类型下拉 -->\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\n class=\"bubble-dropdown-item ${!editor?.isActive('heading') ? 'is-active' : ''}\"\n @click=${this._setParagraph}\n >\n 正文\n </button>\n <button\n class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 1 }) ? 'is-active' : ''}\"\n @click=${() => this._setHeading(1)}\n >\n 标题 1\n </button>\n <button\n class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 2 }) ? 'is-active' : ''}\"\n @click=${() => this._setHeading(2)}\n >\n 标题 2\n </button>\n <button\n class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 3 }) ? 'is-active' : ''}\"\n @click=${() => this._setHeading(3)}\n >\n 标题 3\n </button>\n </div>\n </div>\n\n <div class=\"bubble-divider\"></div>\n\n <!-- 对齐下拉 -->\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\n class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'left' }) ? 'is-active' : ''}\"\n @click=${() => this._setTextAlign('left')}\n >\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\n class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'center' }) ? 'is-active' : ''}\"\n @click=${() => this._setTextAlign('center')}\n >\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\n class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'right' }) ? 'is-active' : ''}\"\n @click=${() => this._setTextAlign('right')}\n >\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 <div class=\"bubble-divider\"></div>\n\n <!-- 行内代码 -->\n <button\n class=\"bubble-btn ${editor?.isActive('code') ? 'is-active' : ''}\"\n @click=${this._toggleCode}\n title=\"行内代码\"\n >\n <svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>\n </button>\n\n <!-- 链接 -->\n <button\n class=\"bubble-btn ${editor?.isActive('link') ? 'is-active' : ''}\"\n @click=${this._setLink}\n title=\"链接\"\n >\n <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 </button>\n\n <!-- 图片 -->\n <button\n class=\"bubble-btn\"\n @click=${this._triggerImageUpload}\n title=\"图片\"\n >\n <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 </button>\n\n <div class=\"bubble-divider\"></div>\n\n <!-- 列表 -->\n <button\n class=\"bubble-btn ${editor?.isActive('bulletList') ? 'is-active' : ''}\"\n @click=${this._toggleBulletList}\n title=\"无序列表\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('orderedList') ? 'is-active' : ''}\"\n @click=${this._toggleOrderedList}\n title=\"有序列表\"\n >\n <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 </button>\n\n <!-- 引用 -->\n <button\n class=\"bubble-btn ${editor?.isActive('blockquote') ? 'is-active' : ''}\"\n @click=${this._toggleBlockquote}\n title=\"引用\"\n >\n <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 </button>\n\n <div class=\"bubble-divider\"></div>\n\n <!-- 表格下拉 -->\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\" 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 </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 </div>\n `\n : ''}\n\n <div class=\"editor-content\"></div>\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._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 <button class=\"image-toolbar-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=\"image-toolbar-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=\"image-toolbar-divider\"></div>\n <div style=\"position: relative;\">\n <button class=\"image-toolbar-btn\" title=\"更多\" @click=${this._toggleImageMoreMenu}>\n <svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"1\"/><circle cx=\"19\" cy=\"12\" r=\"1\"/><circle cx=\"5\" cy=\"12\" r=\"1\"/></svg>\n </button>\n ${this._imageMoreMenuVisible\n ? html`\n <div class=\"image-more-menu\">\n <button class=\"image-more-menu-item\" @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 左对齐\n </button>\n <button class=\"image-more-menu-item\" @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 居中\n </button>\n <button class=\"image-more-menu-item\" @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 右对齐\n </button>\n </div>\n `\n : ''}\n </div>\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"],"names":["QxsBlocksuiteEditor","LitElement","constructor","super","arguments","this","content","placeholder","readonly","preview","_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","_imageMoreMenuVisible","_hasSlashCommand","_isUpdating","_tableEdgeDetectionSetup","_injectCustomStyles","shadow","shadowRoot","remove","styleEl","document","createElement","textContent","appendChild","_useModelValue","hasAttribute","_readonlyValue","_previewValue","_initEditor","el","querySelector","requestAnimationFrame","firstChild","removeChild","useModel","modelValue","getAttribute","contentValue","initialContent","extensions","Document","Paragraph","Text","Bold","Italic","Underline","Strike","Code","Heading","configure","levels","BulletList","OrderedList","ListItem","Blockquote","HorizontalRule","History","Image","inline","allowBase64","Link","openOnClick","HTMLAttributes","rel","TextAlign","types","Table","resizable","TableRow","TableCell","TableHeader","Placeholder","Extension","create","name","addKeyboardShortcuts","Enter","editor","chain","focus","unsetAllMarks","clearNodes","run","Editor","element","editable","on","_updateBubbleMenuPosition","isActive","_showTableCellToolbar","_hideTableCellToolbar","selection","state","$from","node","depth","type","coords","view","coordsAtPos","start","wrapperRect","getBoundingClientRect","left","right","top","_showImageToolbar","_hideImageToolbar","_checkSlashCommand","_setupTableEdgeDetection","_emitContentChange","html","getHTML","dispatchEvent","CustomEvent","detail","bubbles","composed","editorContent","editorWrapper","handleEditorClick","addEventListener","textBefore","doc","textBetween","Math","max","from","endsWith","firstUpdated","updated","changed","has","newContent","commands","setContent","setEditable","disconnectedCallback","destroy","getContent","forceUpdate","requestUpdate","_applyFormat","command","deleteRange","to","_toggleBold","toggleBold","_toggleItalic","toggleItalic","_toggleUnderline","toggleUnderline","_toggleStrike","toggleStrike","_toggleCode","toggleCode","_setHeading","level","toggleHeading","_setParagraph","setParagraph","_toggleBulletList","toggleBulletList","_toggleOrderedList","toggleOrderedList","_toggleBlockquote","toggleBlockquote","_setTextAlign","align","setTextAlign","_setLink","url","window","prompt","setLink","href","_insertTable","rows","cols","insertTable","withHeaderRow","_handleImageUpload","input","files","src","setImage","err","value","_triggerImageUpload","click","_insertTableByClick","_getTableCellRow","_getTableCellCol","bottom","$pos","d","index","_addTableRowAbove","addRowBefore","_addTableRowBelow","addRowAfter","_addTableColumnLeft","addColumnBefore","_addTableColumnRight","addColumnAfter","_deleteTableRow","deleteRow","_deleteTableColumn","deleteColumn","_deleteTable","deleteTable","pos","_toggleImageMoreMenu","_deleteImage","deleteNode","_insertImageAfter","_setImageAlignLeft","setNodeSelection","img","style","display","margin","_setImageAlignCenter","_setImageAlignRight","_getTextLabel","_getAlignLabel","textAlign","bubbleMenu","proseMirror","isInTable","empty","$to","hasTableInSelection","fromAncestor","toAncestor","opacity","visibility","menuRect","width","render","_renderTableGrid","preventDefault","cells","i","row","floor","col","isHighlight","push","styles","css","__decorateClass","property","String","attribute","prototype","Object","safeCustomElement"],"mappings":"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"}
1
+ {"version":3,"file":"blocksuite-editor.mjs","sources":["../../../../packages/components-wc/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 { property, state } from 'lit/decorators.js'\nimport { safeCustomElement } from '../base/define'\n\ntype ToolbarMode = 'slash' | 'header'\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 = '输入 / 唤出快捷命令'\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: 'center',\n parseHTML: element => element.getAttribute('data-align') || 'center',\n renderHTML: attributes => attributes.align ? { 'data-align': String(attributes.align) } : {},\n },\n }\n },\n\n renderHTML({ HTMLAttributes }) {\n const align = String(HTMLAttributes.align || 'center')\n const width = Number(HTMLAttributes.width)\n const margin = align === 'left'\n ? '0 auto 0 0'\n : align === 'right'\n ? '0 0 0 auto'\n : '0 auto'\n\n const style = [\n 'display:block',\n 'max-width:100%',\n 'height:auto',\n `margin:${margin}`,\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: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, sans-serif;\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: 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 }\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: 80px;\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-content .ProseMirror:empty {\n min-height: 80px;\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 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 }\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: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 }\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: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-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 /* 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 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({ type: String, attribute: 'header-always-visible' })\n 'header-always-visible' = 'false'\n\n @property({ type: String, attribute: 'use-model' })\n 'use-model' = 'false'\n\n @property({ type: String, attribute: 'readonly' })\n readonly = 'false'\n\n @property({ type: String, attribute: 'preview' })\n preview = 'false'\n\n @property({ type: String, attribute: 'custom-styles' })\n 'custom-styles' = ''\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 _isEditable(): boolean {\n return !this._readonlyValue && !this._previewValue\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 _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 @property({ type: Object, attribute: 'upload-image' })\n 'upload-image': (file: File) => Promise<string> = 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 @state() 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 _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 _isUpdating = false\n private _pendingImageInsertPos: number | null = null\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._pendingContent ?? modelValue) || '<p></p>'\n : (this._pendingContent ?? contentValue) || '<p></p>'\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.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._pendingContent = null\n\n this._editor.on('selectionUpdate', () => {\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._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: MouseEvent) {\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 html = this._editor.getHTML()\n\n this.dispatchEvent(new CustomEvent('content-change', {\n detail: html,\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: MouseEvent) => {\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')\n ) {\n return\n }\n if (!this._isEditable) {\n return\n }\n this._editor?.chain().focus().run()\n }\n\n editorContent.addEventListener('click', handleEditorClick)\n editorWrapper?.addEventListener('click', handleEditorClick)\n }\n\n private _handleWrapperFocusIn() {\n this._isEditorFocused = true\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 (nextTarget && wrapper?.contains(nextTarget)) {\n return\n }\n this._isEditorFocused = false\n this._tableDropdownOpen = false\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 || 'center')\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 this._initEditor()\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 (changed.has('content') || (changed.has('model-value') && this._useModelValue)) {\n const newContent = this._useModelValue ? this['model-value'] : this.content\n if (newContent !== this._editor.getHTML()) {\n this._editor.commands.setContent(newContent || '<p></p>')\n }\n }\n if (changed.has('readonly') || changed.has('preview')) {\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 this._editor?.destroy()\n this._editor = null\n }\n\n getContent(): string {\n return this._editor?.getHTML() ?? ''\n }\n\n forceUpdate(): void {\n this.requestUpdate()\n if (this._editor) {\n const newContent = this._useModelValue ? this['model-value'] : this.content\n if (newContent !== this._editor.getHTML()) {\n this._editor.commands.setContent(newContent || '<p></p>')\n }\n }\n }\n\n private _applyFormat(command: () => void) {\n this._clearSlashCommandText()\n command()\n }\n\n private _toggleBold() {\n this._applyFormat(() => this._editor?.chain().focus().toggleBold().run())\n }\n\n private _toggleItalic() {\n this._applyFormat(() => this._editor?.chain().focus().toggleItalic().run())\n }\n\n private _toggleUnderline() {\n this._applyFormat(() => this._editor?.chain().focus().toggleUnderline().run())\n }\n\n private _toggleStrike() {\n this._applyFormat(() => this._editor?.chain().focus().toggleStrike().run())\n }\n\n private _toggleCode() {\n this._applyFormat(() => this._editor?.chain().focus().toggleCode().run())\n }\n\n private _setHeading(level: number) {\n this._applyFormat(() => this._editor?.chain().focus().toggleHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }).run())\n }\n\n private _setParagraph() {\n this._applyFormat(() => this._editor?.chain().focus().setParagraph().run())\n }\n\n private _toggleBulletList() {\n this._applyFormat(() => this._editor?.chain().focus().toggleBulletList().run())\n }\n\n private _toggleOrderedList() {\n this._applyFormat(() => this._editor?.chain().focus().toggleOrderedList().run())\n }\n\n private _toggleTaskList() {\n this._applyFormat(() => this._editor?.chain().focus().toggleTaskList().run())\n }\n\n private _toggleBlockquote() {\n this._applyFormat(() => this._editor?.chain().focus().toggleBlockquote().run())\n }\n\n private _setTextAlign(align: string) {\n this._applyFormat(() => this._editor?.chain().focus().setTextAlign(align as any).run())\n }\n\n private _setLink() {\n // eslint-disable-next-line no-alert\n const url = window.prompt('请输入链接地址:')\n if (url) {\n this._applyFormat(() => this._editor?.chain().focus().setLink({ href: url }).run())\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: 'center',\n })\n }\n else {\n this._editor?.chain().focus().setImage({\n src,\n width: initialWidth,\n align: 'center',\n }).run()\n }\n }\n catch (err) {\n console.error('图片上传失败:', err)\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 <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 _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\n return html`\n <div\n class=\"editor-wrapper ${!editor ? 'loading' : ''} ${this._previewValue ? 'preview' : ''}\"\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._previewValue && this._toolbarModeValue === 'header'\n ? html`\n <div class=\"editor-header ${this._isHeaderVisible() ? 'is-visible' : ''}\">\n <div class=\"editor-header__inner\">\n ${this._selectedImage\n ? this._renderImageControls()\n : html`\n <button\n class=\"bubble-btn ${editor?.isActive('bold') ? 'is-active' : ''}\"\n @click=${this._toggleBold}\n title=\"加粗\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('italic') ? 'is-active' : ''}\"\n @click=${this._toggleItalic}\n title=\"斜体\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('underline') ? 'is-active' : ''}\"\n @click=${this._toggleUnderline}\n title=\"下划线\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('strike') ? 'is-active' : ''}\"\n @click=${this._toggleStrike}\n title=\"删除线\"\n >\n <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 </button>\n\n <div class=\"bubble-divider\"></div>\n\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 <div class=\"bubble-divider\"></div>\n\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 <div class=\"bubble-divider\"></div>\n\n <button class=\"bubble-btn ${editor?.isActive('code') ? 'is-active' : ''}\" @click=${this._toggleCode} title=\"行内代码\">\n <svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>\n </button>\n <button class=\"bubble-btn ${editor?.isActive('link') ? 'is-active' : ''}\" @click=${this._setLink} title=\"链接\">\n <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 </button>\n <button class=\"bubble-btn\" @click=${this._triggerImageUpload} title=\"图片\">\n <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 </button>\n\n <div class=\"bubble-divider\"></div>\n\n <button class=\"bubble-btn ${editor?.isActive('bulletList') ? 'is-active' : ''}\" @click=${this._toggleBulletList} title=\"无序列表\">\n <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 </button>\n <button class=\"bubble-btn ${editor?.isActive('orderedList') ? 'is-active' : ''}\" @click=${this._toggleOrderedList} title=\"有序列表\">\n <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 </button>\n <button class=\"bubble-btn ${editor?.isActive('taskList') ? 'is-active' : ''}\" @click=${this._toggleTaskList} title=\"待办列表\">\n <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 </button>\n <button class=\"bubble-btn ${editor?.isActive('blockquote') ? 'is-active' : ''}\" @click=${this._toggleBlockquote} title=\"引用\">\n <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 </button>\n\n <div class=\"bubble-divider\"></div>\n\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\" 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 </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 </div>\n </div>\n `\n : ''}\n\n <!-- Bubble Menu (悬浮操作栏) -->\n ${!this._previewValue && this._toolbarModeValue === 'slash'\n ? html`\n <div class=\"bubble-menu\">\n <!-- 文本格式 -->\n <button\n class=\"bubble-btn ${editor?.isActive('bold') ? 'is-active' : ''}\"\n @click=${this._toggleBold}\n title=\"加粗\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('italic') ? 'is-active' : ''}\"\n @click=${this._toggleItalic}\n title=\"斜体\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('underline') ? 'is-active' : ''}\"\n @click=${this._toggleUnderline}\n title=\"下划线\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('strike') ? 'is-active' : ''}\"\n @click=${this._toggleStrike}\n title=\"删除线\"\n >\n <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 </button>\n\n <div class=\"bubble-divider\"></div>\n\n <!-- 文本类型下拉 -->\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\n class=\"bubble-dropdown-item ${!editor?.isActive('heading') ? 'is-active' : ''}\"\n @click=${this._setParagraph}\n >\n 正文\n </button>\n <button\n class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 1 }) ? 'is-active' : ''}\"\n @click=${() => this._setHeading(1)}\n >\n 标题 1\n </button>\n <button\n class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 2 }) ? 'is-active' : ''}\"\n @click=${() => this._setHeading(2)}\n >\n 标题 2\n </button>\n <button\n class=\"bubble-dropdown-item ${editor?.isActive('heading', { level: 3 }) ? 'is-active' : ''}\"\n @click=${() => this._setHeading(3)}\n >\n 标题 3\n </button>\n </div>\n </div>\n\n <div class=\"bubble-divider\"></div>\n\n <!-- 对齐下拉 -->\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\n class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'left' }) ? 'is-active' : ''}\"\n @click=${() => this._setTextAlign('left')}\n >\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\n class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'center' }) ? 'is-active' : ''}\"\n @click=${() => this._setTextAlign('center')}\n >\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\n class=\"bubble-dropdown-item ${editor?.isActive({ textAlign: 'right' }) ? 'is-active' : ''}\"\n @click=${() => this._setTextAlign('right')}\n >\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 <div class=\"bubble-divider\"></div>\n\n <!-- 行内代码 -->\n <button\n class=\"bubble-btn ${editor?.isActive('code') ? 'is-active' : ''}\"\n @click=${this._toggleCode}\n title=\"行内代码\"\n >\n <svg viewBox=\"0 0 24 24\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>\n </button>\n\n <!-- 链接 -->\n <button\n class=\"bubble-btn ${editor?.isActive('link') ? 'is-active' : ''}\"\n @click=${this._setLink}\n title=\"链接\"\n >\n <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 </button>\n\n <!-- 图片 -->\n <button\n class=\"bubble-btn\"\n @click=${this._triggerImageUpload}\n title=\"图片\"\n >\n <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 </button>\n\n <div class=\"bubble-divider\"></div>\n\n <!-- 列表 -->\n <button\n class=\"bubble-btn ${editor?.isActive('bulletList') ? 'is-active' : ''}\"\n @click=${this._toggleBulletList}\n title=\"无序列表\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('orderedList') ? 'is-active' : ''}\"\n @click=${this._toggleOrderedList}\n title=\"有序列表\"\n >\n <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 </button>\n <button\n class=\"bubble-btn ${editor?.isActive('taskList') ? 'is-active' : ''}\"\n @click=${this._toggleTaskList}\n title=\"待办列表\"\n >\n <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 </button>\n\n <!-- 引用 -->\n <button\n class=\"bubble-btn ${editor?.isActive('blockquote') ? 'is-active' : ''}\"\n @click=${this._toggleBlockquote}\n title=\"引用\"\n >\n <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 </button>\n\n <div class=\"bubble-divider\"></div>\n\n <!-- 表格下拉 -->\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\" 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 </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 </div>\n `\n : ''}\n\n <div class=\"editor-content\" data-empty-hint=${this._resolvedPlaceholder}></div>\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"],"names":["DEFAULT_HEADER_PLACEHOLDER","DEFAULT_SLASH_PLACEHOLDER","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","readonly","preview","_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","_isEditorFocused","_selectedImage","_hasSlashCommand","_slashCommandRange","_isUpdating","_pendingImageInsertPos","_tableEdgeDetectionSetup","_injectCustomStyles","shadow","shadowRoot","remove","styleEl","document","createElement","textContent","appendChild","_useModelValue","hasAttribute","_readonlyValue","_previewValue","_isEditable","_toolbarModeValue","_headerAlwaysVisibleValue","_resolvedPlaceholder","_initEditor","el","querySelector","requestAnimationFrame","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","openOnClick","rel","TextAlign","types","Table","resizable","TableRow","TableCell","TableHeader","Placeholder","Editor","editable","on","_updateBubbleMenuPosition","isActive","_showTableCellToolbar","_hideTableCellToolbar","_syncImageSelectionState","_checkSlashCommand","_setupTableEdgeDetection","_emitContentChange","_toggleTaskItemChecked","event","HTMLInputElement","taskItem","closest","preventDefault","stopPropagation","basePos","view","posAtDOM","searchFrom","Math","max","searchTo","min","state","doc","size","taskItemPos","nodesBetween","node","pos","nodeAt","dispatch","tr","setNodeMarkup","attrs","html","getHTML","dispatchEvent","CustomEvent","detail","bubbles","composed","editorContent","editorWrapper","handleEditorClick","Element","chain","focus","run","addEventListener","_handleWrapperFocusIn","_handleWrapperFocusOut","nextTarget","relatedTarget","wrapper","contains","_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","length","firstUpdated","updated","changed","has","newContent","setContent","setEditable","disconnectedCallback","destroy","getContent","forceUpdate","requestUpdate","_applyFormat","command","_toggleBold","toggleBold","_toggleItalic","toggleItalic","_toggleUnderline","toggleUnderline","_toggleStrike","toggleStrike","_toggleCode","toggleCode","_setHeading","level","toggleHeading","_setParagraph","setParagraph","_toggleBulletList","toggleBulletList","_toggleOrderedList","toggleOrderedList","_toggleTaskList","_toggleBlockquote","toggleBlockquote","_setTextAlign","setTextAlign","_setLink","url","prompt","setLink","href","_insertTable","rows","cols","insertTable","withHeaderRow","_handleImageUpload","input","files","initialWidth","pendingInsertPos","_insertImageAt","setImage","err","_triggerImageUpload","click","_insertTableByClick","_getTableCellRow","_getTableCellCol","bottom","$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","insertContentAt","setNodeSelection","_updateSelectedImageAttributes","_setImageWidth","nextWidth","round","_handleImageWidthInput","rawValue","trim","_setImageAlignLeft","_setImageAlignCenter","_setImageAlignRight","_getTextLabel","_getAlignLabel","textAlign","_renderImageControls","bubbleMenu","proseMirror","isInTable","$to","hasTableInSelection","fromAncestor","toAncestor","opacity","visibility","menuRect","render","_renderTableGrid","cells","i","row","floor","col","isHighlight","push","styles","css","__decorateClass","property","attribute","prototype","Object","safeCustomElement"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export{QxsSubjectAction}from"./subject/action.mjs";export{QxsBlankFill}from"./subject/blank-fill.mjs";export{QxsSubjectLayout}from"./subject/layout.mjs";export{QxsSubjectList}from"./subject/list.mjs";export{QxsPageEnd}from"./subject/page-end.mjs";export{QxsScale}from"./subject/scale.mjs";export{QxsSubjectSingle}from"./subject/single.mjs";export{QxsTextFill}from"./subject/text-fill.mjs";export{QxsSubjectType}from"./subject/type.mjs";
1
+ export{QxsSubjectAction}from"./subject/action.mjs";export{QxsBlankFill}from"./subject/blank-fill.mjs";export{createSubjectDraft}from"./subject/draft.mjs";export{QxsSubjectLayout}from"./subject/layout.mjs";export{QxsPageEnd}from"./subject/page-end.mjs";export{getPaginationMeta,insertPageBreak,rebuildPageBreaksFromPageIndex,removePageBreak,serializeSubjectsWithPageIndex}from"./subject/pagination.mjs";export{collectSubjectElements,serializeSubjectElements,validateSubjectElements}from"./subject/runtime.mjs";export{QxsScale}from"./subject/scale.mjs";export{QxsSubjectSingle}from"./subject/single.mjs";export{moveSubjectItem,reorderSubjects}from"./subject/sort-controller.mjs";export{QxsSubjectSortable}from"./subject/sortable.mjs";export{QxsTextFill}from"./subject/text-fill.mjs";
2
2
  //# sourceMappingURL=entry-subject.mjs.map
package/es/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export{QxsBlocksuiteEditor}from"./editor/blocksuite-editor.mjs";export{register}from"./editor/index.mjs";export{QxsBlankFill}from"./subject/blank-fill.mjs";export{QxsPageEnd}from"./subject/page-end.mjs";export{QxsScale}from"./subject/scale.mjs";export{QxsSubjectAction}from"./subject/action.mjs";export{QxsSubjectLayout}from"./subject/layout.mjs";export{QxsSubjectList}from"./subject/list.mjs";export{QxsSubjectSingle}from"./subject/single.mjs";export{QxsSubjectType}from"./subject/type.mjs";export{QxsTextFill}from"./subject/text-fill.mjs";
1
+ export{QxsBlocksuiteEditor}from"./editor/blocksuite-editor.mjs";export{register}from"./editor/index.mjs";export{collectSubjectElements,serializeSubjectElements,validateSubjectElements}from"./subject/runtime.mjs";export{createSubjectDraft}from"./subject/draft.mjs";export{getPaginationMeta,insertPageBreak,rebuildPageBreaksFromPageIndex,removePageBreak,serializeSubjectsWithPageIndex}from"./subject/pagination.mjs";export{moveSubjectItem,reorderSubjects}from"./subject/sort-controller.mjs";export{QxsBlankFill}from"./subject/blank-fill.mjs";export{QxsPageEnd}from"./subject/page-end.mjs";export{QxsScale}from"./subject/scale.mjs";export{QxsSubjectAction}from"./subject/action.mjs";export{QxsSubjectLayout}from"./subject/layout.mjs";export{QxsSubjectSingle}from"./subject/single.mjs";export{QxsSubjectSortable}from"./subject/sortable.mjs";export{QxsTextFill}from"./subject/text-fill.mjs";
2
2
  //# sourceMappingURL=index.mjs.map