@qxs-bns/components-wc 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/editor/blocksuite-editor.mjs +25 -15
- package/es/editor/blocksuite-editor.mjs.map +1 -1
- package/es/editor/index.mjs +1 -1
- package/es/editor/index.mjs.map +1 -1
- package/es/node_modules/.pnpm/@tiptap_extension-placeholder@3.19.0_@tiptap_extensions@3.19.0_@tiptap_core@3.19.0_@tiptap_pm@3.20.5__@tiptap_pm@3.20.5_/node_modules/@tiptap/extension-placeholder/dist/index.mjs +2 -0
- package/es/node_modules/.pnpm/@tiptap_extension-placeholder@3.19.0_@tiptap_extensions@3.19.0_@tiptap_core@3.19.0_@tiptap_pm@3.20.5__@tiptap_pm@3.20.5_/node_modules/@tiptap/extension-placeholder/dist/index.mjs.map +1 -0
- package/es/node_modules/.pnpm/@tiptap_extensions@3.19.0_@tiptap_core@3.19.0_@tiptap_pm@3.20.5__@tiptap_pm@3.20.5/node_modules/@tiptap/extensions/dist/index.mjs +2 -0
- package/es/node_modules/.pnpm/@tiptap_extensions@3.19.0_@tiptap_core@3.19.0_@tiptap_pm@3.20.5__@tiptap_pm@3.20.5/node_modules/@tiptap/extensions/dist/index.mjs.map +1 -0
- package/es/subject/action.mjs +2 -2
- package/es/subject/action.mjs.map +1 -1
- package/es/subject/layout.mjs +4 -4
- package/es/subject/layout.mjs.map +1 -1
- package/es/subject/list.mjs +9 -12
- package/es/subject/list.mjs.map +1 -1
- package/lib/editor/blocksuite-editor.cjs +14 -4
- package/lib/editor/blocksuite-editor.cjs.map +1 -1
- package/lib/editor/index.cjs +1 -1
- package/lib/editor/index.cjs.map +1 -1
- package/lib/node_modules/.pnpm/@tiptap_extension-placeholder@3.19.0_@tiptap_extensions@3.19.0_@tiptap_core@3.19.0_@tiptap_pm@3.20.5__@tiptap_pm@3.20.5_/node_modules/@tiptap/extension-placeholder/dist/index.cjs +2 -0
- package/lib/node_modules/.pnpm/@tiptap_extension-placeholder@3.19.0_@tiptap_extensions@3.19.0_@tiptap_core@3.19.0_@tiptap_pm@3.20.5__@tiptap_pm@3.20.5_/node_modules/@tiptap/extension-placeholder/dist/index.cjs.map +1 -0
- package/lib/node_modules/.pnpm/@tiptap_extensions@3.19.0_@tiptap_core@3.19.0_@tiptap_pm@3.20.5__@tiptap_pm@3.20.5/node_modules/@tiptap/extensions/dist/index.cjs +2 -0
- package/lib/node_modules/.pnpm/@tiptap_extensions@3.19.0_@tiptap_core@3.19.0_@tiptap_pm@3.20.5__@tiptap_pm@3.20.5/node_modules/@tiptap/extensions/dist/index.cjs.map +1 -0
- package/lib/subject/action.cjs +2 -2
- package/lib/subject/action.cjs.map +1 -1
- package/lib/subject/layout.cjs +2 -2
- package/lib/subject/layout.cjs.map +1 -1
- package/lib/subject/list.cjs +8 -11
- package/lib/subject/list.cjs.map +1 -1
- package/package.json +29 -27
- package/types/base/define.d.ts +1 -0
- package/types/base/uid.d.ts +1 -0
- package/types/editor/blocksuite-editor.d.ts +84 -0
- package/types/editor/index.d.ts +3 -0
- package/types/index.d.ts +4 -0
- package/types/subject/action.d.ts +23 -0
- package/types/subject/blank-fill.d.ts +49 -0
- package/types/subject/index.d.ts +20 -0
- package/types/subject/layout.d.ts +7 -0
- package/types/subject/list.d.ts +43 -0
- package/types/subject/page-end.d.ts +10 -0
- package/types/subject/rich-text.d.ts +30 -0
- package/types/subject/scale.d.ts +42 -0
- package/types/subject/single.d.ts +79 -0
- package/types/subject/text-fill.d.ts +54 -0
- package/types/subject/type.d.ts +7 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocksuite-editor.mjs","sources":["../../../../packages/components-wc/src/editor/blocksuite-editor.ts"],"sourcesContent":["import { Editor } 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 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 Placeholder from '@tiptap/extension-placeholder'\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 }\n\n .editor-wrapper:focus-within {\n border-color: var(--qxs-color-primary, #3D61E3);\n box-shadow: 0 0 0 2px rgba(61, 97, 227, 0.1);\n }\n\n .editor-wrapper.preview {\n border: none;\n border-radius: 0;\n background: transparent;\n }\n\n .editor-wrapper.is-edit {\n border: 1px solid #dcdfe6;\n border-radius: 3px;\n background: #fff;\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 margin-top: 80px;\n text-align: center;\n }\n\n .editor-content .ProseMirror:empty {\n min-height: 200px;\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 .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 /* Table Edge Add Button */\n .table-edge-add {\n position: absolute;\n z-index: 40;\n display: none;\n width: 20px;\n height: 20px;\n align-items: center;\n justify-content: center;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n color: #606266;\n transition: all 0.15s;\n }\n\n .table-edge-add:hover {\n background: #ecf5ff;\n border-color: var(--qxs-color-primary, #3D61E3);\n color: var(--qxs-color-primary, #3D61E3);\n }\n\n .table-edge-add.visible {\n display: flex;\n }\n\n .table-edge-add-row {\n width: 100%;\n height: 8px;\n left: 0;\n border-radius: 0 0 4px 4px;\n }\n\n .table-edge-add-col {\n height: 100%;\n width: 8px;\n top: 0;\n border-radius: 0 4px 4px 0;\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-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: Boolean, attribute: 'readonly' })\n readonly = false\n\n @property({ type: Boolean, attribute: 'preview' })\n preview = false\n\n @property({ type: Boolean, attribute: 'is-edit' })\n isEdit = false\n\n @property({ type: Object, attribute: 'upload-image' })\n uploadImage: (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 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 _isLoading = true\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 _tableEdgeHover: { type: 'row' | 'col' | null, index: number, position: { x: number, y: number } } = { type: null, index: 0, position: { x: 0, y: 0 } }\n @state() private _imageToolbar: { x: number, y: number, visible: boolean } = { x: 0, y: 0, visible: false }\n @state() private _imageMoreMenuVisible = false\n @state() private _hasSlashCommand = 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 this._isLoading = false\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: '输入 / 唤出快捷命令',\n }),\n ]\n\n this._editor = new Editor({\n element: el,\n extensions,\n content: (this._pendingContent ?? this.content) || '<p></p>',\n editable: !this.readonly,\n })\n\n this._pendingContent = null\n\n this._editor.on('selectionUpdate', () => {\n this.requestUpdate()\n this._updateBubbleMenuPosition()\n if (this._editor?.isActive('table')) {\n this._showTableCellToolbar()\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 } else {\n this._hideImageToolbar()\n }\n }\n })\n\n this._editor.on('transaction', () => {\n this.requestUpdate()\n if (this._editor?.isActive('table')) {\n this._showTableCellToolbar()\n } else {\n this._hideTableCellToolbar()\n }\n this._checkSlashCommand()\n this._setupTableEdgeDetection()\n })\n }\n\n private _tableEdgeDetectionSetup = false\n\n private _setupTableEdgeDetection() {\n const editorContent = this.shadowRoot?.querySelector('.editor-content')\n if (!editorContent || this._tableEdgeDetectionSetup) return\n \n this._tableEdgeDetectionSetup = true\n \n editorContent.addEventListener('mousemove', (e: Event) => {\n this._handleTableEdgeMouseMove(e as MouseEvent)\n })\n\n editorContent.addEventListener('mouseleave', () => {\n this._tableEdgeHover = { type: null, index: 0, position: { x: 0, y: 0 } }\n })\n\n // Image click to select\n editorContent.addEventListener('click', (e: Event) => {\n const target = e.target as HTMLElement\n if (target.tagName === 'IMG') {\n const pos = this._editor?.view.posAtDOM(target, 0)\n if (pos !== undefined) {\n this._editor?.chain().focus().setNodeSelection(pos).run()\n }\n }\n })\n }\n\n private _handleTableEdgeMouseMove(e: MouseEvent) {\n if (!this._editor?.isActive('table')) {\n this._tableEdgeHover = { type: null, index: 0, position: { x: 0, y: 0 } }\n this.requestUpdate()\n return\n }\n\n const target = e.target as HTMLElement\n const table = target.closest('table')\n if (!table) {\n this._tableEdgeHover = { type: null, index: 0, position: { x: 0, y: 0 } }\n this.requestUpdate()\n return\n }\n\n const tableRect = table.getBoundingClientRect()\n const editorWrapper = this.shadowRoot?.querySelector('.editor-wrapper')\n if (!editorWrapper) return\n const wrapperRect = editorWrapper.getBoundingClientRect()\n\n const relativeX = e.clientX - wrapperRect.left\n const relativeY = e.clientY - wrapperRect.top\n\n const edgeThreshold = 10\n const rowHeight = tableRect.height / table.rows.length\n\n for (let i = 0; i < table.rows.length; i++) {\n const rowTop = tableRect.top + i * rowHeight\n const rowBottom = rowTop + rowHeight\n \n if (e.clientY >= rowTop - edgeThreshold && e.clientY <= rowTop + edgeThreshold) {\n this._tableEdgeHover = {\n type: 'row',\n index: i,\n position: { x: relativeX, y: rowTop - wrapperRect.top }\n }\n this.requestUpdate()\n return\n }\n \n if (e.clientY >= rowBottom - edgeThreshold && e.clientY <= rowBottom + edgeThreshold) {\n this._tableEdgeHover = {\n type: 'row',\n index: i + 1,\n position: { x: relativeX, y: rowBottom - wrapperRect.top }\n }\n this.requestUpdate()\n return\n }\n }\n\n const colWidth = tableRect.width / table.rows[0]?.cells.length || 1\n for (let i = 0; i < (table.rows[0]?.cells.length || 0); i++) {\n const colLeft = tableRect.left + i * colWidth\n const colRight = colLeft + colWidth\n \n if (e.clientX >= colLeft - edgeThreshold && e.clientX <= colLeft + edgeThreshold) {\n this._tableEdgeHover = {\n type: 'col',\n index: i,\n position: { x: colLeft - wrapperRect.left, y: relativeY }\n }\n this.requestUpdate()\n return\n }\n \n if (e.clientX >= colRight - edgeThreshold && e.clientX <= colRight + edgeThreshold) {\n this._tableEdgeHover = {\n type: 'col',\n index: i + 1,\n position: { x: colRight - wrapperRect.left, y: relativeY }\n }\n this.requestUpdate()\n return\n }\n }\n\n this._tableEdgeHover = { type: null, index: 0, position: { x: 0, y: 0 } }\n this.requestUpdate()\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._initEditor()\n }\n\n updated(changed: Map<string, unknown>) {\n if (this._editor) {\n if (changed.has('content')) {\n this._editor.commands.setContent(this.content || '<p></p>')\n }\n if (changed.has('readonly')) {\n this._editor.setEditable(!this.readonly)\n }\n return\n }\n\n if (changed.has('content')) {\n this._pendingContent = this.content\n }\n\n const el = this.shadowRoot?.querySelector<HTMLElement>('.editor-content')\n if (el && !this._editor) {\n this._initEditor()\n }\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 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 _unsetLink() {\n this._applyFormat(() => this._editor?.chain().focus().unsetLink().run())\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.uploadImage(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 _insertHorizontalRule() {\n this._editor?.chain().focus().setHorizontalRule().run()\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 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 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 this._tableCellToolbar = { ...this._tableCellToolbar, visible: false }\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 this._imageToolbar = { x: pos.x, y: pos.y, visible: true }\n this._imageMoreMenuVisible = false\n }\n\n private _hideImageToolbar() {\n this._imageToolbar = { ...this._imageToolbar, visible: false }\n this._imageMoreMenuVisible = false\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 _updateImageToolbarPosition() {\n requestAnimationFrame(() => {\n const editor = this._editor\n if (!editor) return\n\n const { selection } = editor.state\n const { $from } = selection\n\n // Find if we're inside an image node\n const imageNode = $from.node($from.depth).type.name === 'image'\n ? $from.node($from.depth)\n : null\n\n if (imageNode) {\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 } else {\n this._hideImageToolbar()\n }\n })\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 } 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 ${this._isLoading ? 'loading' : ''} ${this.preview ? 'preview' : ''}\">\n ${this._isLoading ? html`\n <div class=\"loading-placeholder\">\n <div class=\"loading-spinner\"></div>\n <span>编辑器加载中...</span>\n </div>\n ` : ''}\n <input\n type=\"file\"\n accept=\"image/*\"\n class=\"image-input\"\n @change=${this._handleImageUpload}\n />\n\n <!-- Bubble Menu (悬浮操作栏) -->\n ${!this.preview ? 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 <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 ? 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 ${this._tableCellToolbar.cellCol === 0 ? 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 ${this._tableCellToolbar.cellRow === 0 && this._tableCellToolbar.cellCol === 0 ? 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 </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","readonly","preview","isEdit","uploadImage","async","Promise","resolve","reject","reader","FileReader","onload","e","target","result","onerror","readAsDataURL","file","_editor","_pendingContent","_tableRows","_tableCols","_hoverRow","_hoverCol","_tableDropdownOpen","_isLoading","_tableCellToolbar","x","y","visible","cellRow","cellCol","_tableEdgeHover","type","index","position","_imageToolbar","_imageMoreMenuVisible","_hasSlashCommand","_tableEdgeDetectionSetup","_initEditor","el","shadowRoot","querySelector","requestAnimationFrame","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","placeholder","Editor","element","editable","on","requestUpdate","_updateBubbleMenuPosition","isActive","_showTableCellToolbar","_hideTableCellToolbar","editor","selection","state","$from","node","depth","name","coords","view","coordsAtPos","start","wrapperRect","getBoundingClientRect","left","right","top","_showImageToolbar","_hideImageToolbar","_checkSlashCommand","_setupTableEdgeDetection","editorContent","addEventListener","_handleTableEdgeMouseMove","tagName","pos","posAtDOM","chain","focus","setNodeSelection","run","table","closest","tableRect","editorWrapper","relativeX","clientX","relativeY","clientY","edgeThreshold","rowHeight","height","rows","length","i","rowTop","rowBottom","colWidth","width","cells","colLeft","colRight","textBefore","doc","textBetween","Math","max","from","endsWith","firstUpdated","updated","changed","has","commands","setContent","setEditable","disconnectedCallback","destroy","getContent","getHTML","_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","_unsetLink","unsetLink","_insertTable","cols","insertTable","withHeaderRow","_handleImageUpload","input","files","src","setImage","err","value","_triggerImageUpload","click","_insertTableByClick","_insertHorizontalRule","setHorizontalRule","_getTableCellRow","_getTableCellCol","bottom","$pos","d","_addTableRowAbove","addRowBefore","_addTableRowBelow","addRowAfter","_addTableColumnLeft","addColumnBefore","_addTableColumnRight","addColumnAfter","_deleteTableRow","deleteRow","_deleteTableColumn","deleteColumn","_deleteTable","deleteTable","_toggleImageMoreMenu","_deleteImage","deleteNode","_insertImageAfter","_setImageAlignLeft","img","style","display","margin","_setImageAlignCenter","_setImageAlignRight","_updateImageToolbarPosition","_getTextLabel","_getAlignLabel","textAlign","bubbleMenu","proseMirror","isInTable","empty","$to","hasTableInSelection","fromAncestor","toAncestor","opacity","visibility","menuRect","render","html","_renderTableGrid","preventDefault","row","floor","col","isHighlight","push","styles","css","__decorateClass","property","String","attribute","prototype","Boolean","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 } 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 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 Placeholder from '@tiptap/extension-placeholder'\nimport { Extension } from '@tiptap/core'\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 box-shadow: 0 0 0 2px rgba(61, 97, 227, 0.1);\n }\n\n .editor-wrapper.preview {\n border: none;\n border-radius: 0;\n background: transparent;\n }\n\n .editor-wrapper.is-edit {\n border: 1px solid #dcdfe6;\n border-radius: 3px;\n background: #fff;\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 /* Table Edge Add Button */\n .table-edge-add {\n position: absolute;\n z-index: 40;\n display: none;\n width: 20px;\n height: 20px;\n align-items: center;\n justify-content: center;\n background: #fff;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n color: #606266;\n transition: all 0.15s;\n }\n\n .table-edge-add:hover {\n background: #ecf5ff;\n border-color: var(--qxs-color-primary, #3D61E3);\n color: var(--qxs-color-primary, #3D61E3);\n }\n\n .table-edge-add.visible {\n display: flex;\n }\n\n .table-edge-add-row {\n width: 100%;\n height: 8px;\n left: 0;\n border-radius: 0 0 4px 4px;\n }\n\n .table-edge-add-col {\n height: 100%;\n width: 8px;\n top: 0;\n border-radius: 0 4px 4px 0;\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-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 modelValue = ''\n\n @property({ type: String, attribute: 'use-model' })\n useModelAttr = 'false'\n\n @property({ type: String, attribute: 'auto-sync' })\n autoSyncAttr = 'true'\n\n @property({ type: String, attribute: 'readonly' })\n readonlyAttr = 'false'\n\n @property({ type: String, attribute: 'preview' })\n previewAttr = 'false'\n\n @property({ type: String, attribute: 'is-edit' })\n isEditAttr = 'false'\n\n get useModel(): boolean {\n return this.useModelAttr === 'true'\n }\n\n set useModel(value: boolean) {\n this.useModelAttr = String(value)\n }\n\n get autoSync(): boolean {\n return this.autoSyncAttr !== 'false'\n }\n\n set autoSync(value: boolean) {\n this.autoSyncAttr = String(value)\n }\n\n get readonly(): boolean {\n return this.readonlyAttr !== 'false'\n }\n\n set readonly(value: boolean) {\n this.readonlyAttr = String(value)\n }\n\n get preview(): boolean {\n return this.previewAttr !== 'false'\n }\n\n set preview(value: boolean) {\n this.previewAttr = String(value)\n }\n\n get isEdit(): boolean {\n return this.isEditAttr === 'true'\n }\n\n set isEdit(value: boolean) {\n this.isEditAttr = String(value)\n }\n\n @property({ type: Object, attribute: 'upload-image' })\n uploadImage: (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 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 _isLoading = true\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 _tableEdgeHover: { type: 'row' | 'col' | null, index: number, position: { x: number, y: number } } = { type: null, index: 0, position: { x: 0, y: 0 } }\n @state() private _imageToolbar: { x: number, y: number, visible: boolean } = { x: 0, y: 0, visible: false }\n @state() private _imageMoreMenuVisible = false\n @state() private _hasSlashCommand = false\n private _isInitializing = 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 console.log('[BlocksuiteEditor] _initEditor - Before clear, childNodes:', el.childNodes.length)\n console.log('[BlocksuiteEditor] _initEditor - Before clear, innerHTML:', el.innerHTML.substring(0, 200))\n\n // 设置初始化标志,防止触发循环更新\n this._isInitializing = true\n\n // 清空容器,确保 Tiptap 创建时容器是空的\n // 使用 removeChild 清空所有子节点,比 innerHTML 更彻底\n while (el.firstChild) {\n el.removeChild(el.firstChild)\n }\n\n console.log('[BlocksuiteEditor] _initEditor - After clear, childNodes:', el.childNodes.length)\n console.log('[BlocksuiteEditor] _initEditor - After clear, innerHTML:', el.innerHTML)\n\n this._isLoading = false\n\n const useModel = this.useModel || this.hasAttribute('use-model')\n const modelValue = this.getAttribute('model-value') ?? this.modelValue\n const contentValue = this.content\n\n const initialContent = useModel\n ? (this._pendingContent ?? modelValue) || '<p></p>'\n : (this._pendingContent ?? contentValue) || '<p></p>'\n\n console.log('[BlocksuiteEditor] _initEditor - initialContent:', initialContent.substring(0, 100))\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: '输入 / 唤出快捷命令',\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.readonly,\n content: initialContent,\n })\n\n console.log('[BlocksuiteEditor] After Editor created, childNodes:', el.childNodes.length)\n console.log('[BlocksuiteEditor] After Editor created, innerHTML:', el.innerHTML.substring(0, 200))\n\n this._pendingContent = null\n\n // 延迟重置初始化标志,确保编辑器完全初始化\n requestAnimationFrame(() => {\n this._isInitializing = false\n // 初始化完成后手动触发一次内容同步\n this._emitContentChange()\n })\n\n this._editor.on('selectionUpdate', () => {\n this.requestUpdate()\n this._updateBubbleMenuPosition()\n if (this._editor?.isActive('table')) {\n this._showTableCellToolbar()\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 } else {\n this._hideImageToolbar()\n }\n }\n })\n\n this._editor.on('transaction', () => {\n this.requestUpdate()\n if (this._editor?.isActive('table')) {\n this._showTableCellToolbar()\n } else {\n this._hideTableCellToolbar()\n }\n this._checkSlashCommand()\n this._setupTableEdgeDetection()\n this._emitContentChange()\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 // 初始化期间不触发事件,防止循环更新\n if (this._isInitializing) return\n\n this.dispatchEvent(new CustomEvent('content-change', {\n detail: html,\n bubbles: true,\n composed: true,\n }))\n if (this.autoSync) {\n this.modelValue = html\n }\n }\n\n private _setupTableEdgeDetection() {\n const editorContent = this.shadowRoot?.querySelector('.editor-content')\n if (!editorContent || this._tableEdgeDetectionSetup) return\n \n this._tableEdgeDetectionSetup = true\n \n editorContent.addEventListener('mousemove', (e: Event) => {\n this._handleTableEdgeMouseMove(e as MouseEvent)\n })\n\n editorContent.addEventListener('mouseleave', () => {\n this._tableEdgeHover = { type: null, index: 0, position: { x: 0, y: 0 } }\n })\n\n // Image click to select\n editorContent.addEventListener('click', (e: Event) => {\n const target = e.target as HTMLElement\n if (target.tagName === 'IMG') {\n const pos = this._editor?.view.posAtDOM(target, 0)\n if (pos !== undefined) {\n this._editor?.chain().focus().setNodeSelection(pos).run()\n }\n }\n })\n }\n\n private _handleTableEdgeMouseMove(e: MouseEvent) {\n if (!this._editor?.isActive('table')) {\n this._tableEdgeHover = { type: null, index: 0, position: { x: 0, y: 0 } }\n this.requestUpdate()\n return\n }\n\n const target = e.target as HTMLElement\n const table = target.closest('table')\n if (!table) {\n this._tableEdgeHover = { type: null, index: 0, position: { x: 0, y: 0 } }\n this.requestUpdate()\n return\n }\n\n const tableRect = table.getBoundingClientRect()\n const editorWrapper = this.shadowRoot?.querySelector('.editor-wrapper')\n if (!editorWrapper) return\n const wrapperRect = editorWrapper.getBoundingClientRect()\n\n const relativeX = e.clientX - wrapperRect.left\n const relativeY = e.clientY - wrapperRect.top\n\n const edgeThreshold = 10\n const rowHeight = tableRect.height / table.rows.length\n\n for (let i = 0; i < table.rows.length; i++) {\n const rowTop = tableRect.top + i * rowHeight\n const rowBottom = rowTop + rowHeight\n \n if (e.clientY >= rowTop - edgeThreshold && e.clientY <= rowTop + edgeThreshold) {\n this._tableEdgeHover = {\n type: 'row',\n index: i,\n position: { x: relativeX, y: rowTop - wrapperRect.top }\n }\n this.requestUpdate()\n return\n }\n \n if (e.clientY >= rowBottom - edgeThreshold && e.clientY <= rowBottom + edgeThreshold) {\n this._tableEdgeHover = {\n type: 'row',\n index: i + 1,\n position: { x: relativeX, y: rowBottom - wrapperRect.top }\n }\n this.requestUpdate()\n return\n }\n }\n\n const colWidth = tableRect.width / table.rows[0]?.cells.length || 1\n for (let i = 0; i < (table.rows[0]?.cells.length || 0); i++) {\n const colLeft = tableRect.left + i * colWidth\n const colRight = colLeft + colWidth\n \n if (e.clientX >= colLeft - edgeThreshold && e.clientX <= colLeft + edgeThreshold) {\n this._tableEdgeHover = {\n type: 'col',\n index: i,\n position: { x: colLeft - wrapperRect.left, y: relativeY }\n }\n this.requestUpdate()\n return\n }\n \n if (e.clientX >= colRight - edgeThreshold && e.clientX <= colRight + edgeThreshold) {\n this._tableEdgeHover = {\n type: 'col',\n index: i + 1,\n position: { x: colRight - wrapperRect.left, y: relativeY }\n }\n this.requestUpdate()\n return\n }\n }\n\n this._tableEdgeHover = { type: null, index: 0, position: { x: 0, y: 0 } }\n this.requestUpdate()\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._initEditor()\n }\n\n updated(changed: Map<string, unknown>) {\n if (this._editor) {\n if (changed.has('content') || (changed.has('modelValue') && this.useModel)) {\n const newContent = this.useModel ? this.modelValue : 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.readonly)\n }\n return\n }\n\n // 编辑器未初始化时,只保存待处理内容,不重复初始化\n if (changed.has('content')) {\n this._pendingContent = this.content\n }\n\n if (changed.has('modelValue') && this.useModel) {\n this._pendingContent = this.modelValue\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.useModel ? this.modelValue : this.content\n if (newContent !== this._editor.getHTML()) {\n this._editor.commands.setContent(newContent || '<p></p>')\n }\n }\n }\n\n forceSync(): void {\n this.forceUpdate()\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 _unsetLink() {\n this._applyFormat(() => this._editor?.chain().focus().unsetLink().run())\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.uploadImage(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 _insertHorizontalRule() {\n this._editor?.chain().focus().setHorizontalRule().run()\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 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 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 this._tableCellToolbar = { ...this._tableCellToolbar, visible: false }\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 this._imageToolbar = { x: pos.x, y: pos.y, visible: true }\n this._imageMoreMenuVisible = false\n }\n\n private _hideImageToolbar() {\n this._imageToolbar = { ...this._imageToolbar, visible: false }\n this._imageMoreMenuVisible = false\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 _updateImageToolbarPosition() {\n requestAnimationFrame(() => {\n const editor = this._editor\n if (!editor) return\n\n const { selection } = editor.state\n const { $from } = selection\n\n // Find if we're inside an image node\n const imageNode = $from.node($from.depth).type.name === 'image'\n ? $from.node($from.depth)\n : null\n\n if (imageNode) {\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 } else {\n this._hideImageToolbar()\n }\n })\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 } 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 ${this._isLoading ? 'loading' : ''} ${this.preview ? 'preview' : ''}\">\n ${this._isLoading ? html`\n <div class=\"loading-placeholder\">\n <div class=\"loading-spinner\"></div>\n <span>编辑器加载中...</span>\n </div>\n ` : ''}\n <input\n type=\"file\"\n accept=\"image/*\"\n class=\"image-input\"\n @change=${this._handleImageUpload}\n />\n\n <!-- Bubble Menu (悬浮操作栏) -->\n ${!this.preview ? 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 <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 ? 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 ${this._tableCellToolbar.cellCol === 0 ? 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 ${this._tableCellToolbar.cellRow === 0 && this._tableCellToolbar.cellCol === 0 ? 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 </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","modelValue","useModelAttr","autoSyncAttr","readonlyAttr","previewAttr","isEditAttr","uploadImage","async","Promise","resolve","reject","reader","FileReader","onload","e","target","result","onerror","readAsDataURL","file","_editor","_pendingContent","_tableRows","_tableCols","_hoverRow","_hoverCol","_tableDropdownOpen","_isLoading","_tableCellToolbar","x","y","visible","cellRow","cellCol","_tableEdgeHover","type","index","position","_imageToolbar","_imageMoreMenuVisible","_hasSlashCommand","_isInitializing","_tableEdgeDetectionSetup","useModel","value","String","autoSync","readonly","preview","isEdit","_initEditor","el","shadowRoot","querySelector","requestAnimationFrame","firstChild","removeChild","hasAttribute","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","placeholder","Extension","create","name","addKeyboardShortcuts","Enter","editor","chain","focus","unsetAllMarks","clearNodes","run","Editor","element","editable","_emitContentChange","on","requestUpdate","_updateBubbleMenuPosition","isActive","_showTableCellToolbar","_hideTableCellToolbar","selection","state","$from","node","depth","coords","view","coordsAtPos","start","wrapperRect","getBoundingClientRect","left","right","top","_showImageToolbar","_hideImageToolbar","_checkSlashCommand","_setupTableEdgeDetection","html","getHTML","dispatchEvent","CustomEvent","detail","bubbles","composed","editorContent","addEventListener","_handleTableEdgeMouseMove","tagName","pos","posAtDOM","setNodeSelection","table","closest","tableRect","editorWrapper","relativeX","clientX","relativeY","clientY","edgeThreshold","rowHeight","height","rows","length","i","rowTop","rowBottom","colWidth","width","cells","colLeft","colRight","textBefore","doc","textBetween","Math","max","from","endsWith","firstUpdated","updated","changed","has","newContent","commands","setContent","setEditable","disconnectedCallback","destroy","getContent","forceUpdate","forceSync","_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","_unsetLink","unsetLink","_insertTable","cols","insertTable","withHeaderRow","_handleImageUpload","input","files","src","setImage","err","_triggerImageUpload","click","_insertTableByClick","_insertHorizontalRule","setHorizontalRule","_getTableCellRow","_getTableCellCol","bottom","$pos","d","_addTableRowAbove","addRowBefore","_addTableRowBelow","addRowAfter","_addTableColumnLeft","addColumnBefore","_addTableColumnRight","addColumnAfter","_deleteTableRow","deleteRow","_deleteTableColumn","deleteColumn","_deleteTable","deleteTable","_toggleImageMoreMenu","_deleteImage","deleteNode","_insertImageAfter","_setImageAlignLeft","img","style","display","margin","_setImageAlignCenter","_setImageAlignRight","_updateImageToolbarPosition","_getTextLabel","_getAlignLabel","textAlign","bubbleMenu","proseMirror","isInTable","empty","$to","hasTableInSelection","fromAncestor","toAncestor","opacity","visibility","menuRect","render","_renderTableGrid","preventDefault","row","floor","col","isHighlight","push","styles","css","__decorateClass","property","attribute","prototype","Object","safeCustomElement"],"mappings":"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"}
|
package/es/editor/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import{QxsBlocksuiteEditor as e}from"./blocksuite-editor.mjs";function t(){}customElements.get("qxs-blocksuite-editor")||customElements.define("qxs-blocksuite-editor",e);export{e as QxsBlocksuiteEditor,t as register};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/es/editor/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../packages/components-wc/src/editor/index.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../packages/components-wc/src/editor/index.ts"],"sourcesContent":["import { QxsBlocksuiteEditor } from './blocksuite-editor'\nexport { QxsBlocksuiteEditor }\n\nif (!customElements.get('qxs-blocksuite-editor')) {\n customElements.define('qxs-blocksuite-editor', QxsBlocksuiteEditor)\n}\n\nexport function register() {}\n"],"names":["register","customElements","get","define","QxsBlocksuiteEditor"],"mappings":"8DAOO,SAASA,IAAY,CAJvBC,eAAeC,IAAI,0BACtBD,eAAeE,OAAO,wBAAyBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../../../../../../../node_modules/.pnpm/@tiptap+extension-placeholder@3.19.0_@tiptap+extensions@3.19.0_@tiptap+core@3.19.0_@tiptap+pm@3.20.5__@tiptap+pm@3.20.5_/node_modules/@tiptap/extension-placeholder/dist/index.js"],"sourcesContent":["// src/index.ts\nimport { Placeholder } from \"@tiptap/extensions\";\nimport { Placeholder as Placeholder2 } from \"@tiptap/extensions\";\nvar index_default = Placeholder;\nexport {\n Placeholder2 as Placeholder,\n index_default as default\n};\n//# sourceMappingURL=index.js.map"],"names":["index_default","Placeholder"],"mappings":"+KAKA,IAAOA,EAAQC","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Extension as e,callOrReturn as t,getExtensionField as o,isNodeEmpty as r,isNodeSelection as s}from"@tiptap/core";import{Plugin as n,PluginKey as i}from"../../../../../prosemirror-state@1.4.4/node_modules/prosemirror-state/dist/index.mjs";import{dropCursor as d}from"../../../../../prosemirror-dropcursor@1.8.2/node_modules/prosemirror-dropcursor/dist/index.mjs";import{DecorationSet as a,Decoration as c}from"../../../../../prosemirror-view@1.41.7/node_modules/prosemirror-view/dist/index.mjs";import{gapCursor as l}from"../../../../../prosemirror-gapcursor@1.4.1/node_modules/prosemirror-gapcursor/dist/index.mjs";import{history as p,redo as u,undo as h}from"../../../../../prosemirror-history@1.5.0/node_modules/prosemirror-history/dist/index.mjs";e.create({name:"characterCount",addOptions:()=>({limit:null,mode:"textSize",textCounter:e=>e.length,wordCounter:e=>e.split(" ").filter(e=>""!==e).length}),addStorage:()=>({characters:()=>0,words:()=>0}),onBeforeCreate(){this.storage.characters=e=>{const t=(null==e?void 0:e.node)||this.editor.state.doc;if("textSize"===((null==e?void 0:e.mode)||this.options.mode)){const e=t.textBetween(0,t.content.size,void 0," ");return this.options.textCounter(e)}return t.nodeSize},this.storage.words=e=>{const t=(null==e?void 0:e.node)||this.editor.state.doc,o=t.textBetween(0,t.content.size," "," ");return this.options.wordCounter(o)}},addProseMirrorPlugins(){let e=!1;return[new n({key:new i("characterCount"),appendTransaction:(t,o,r)=>{if(e)return;const s=this.options.limit;if(null==s||0===s)return void(e=!0);const n=this.storage.characters({node:r.doc});if(n>s){const t=0,o=n-s,i=r.tr.deleteRange(t,o);return e=!0,i}e=!0},filterTransaction:(e,t)=>{const o=this.options.limit;if(!e.docChanged||0===o||null==o)return!0;const r=this.storage.characters({node:t.doc}),s=this.storage.characters({node:e.doc});if(s<=o)return!0;if(r>o&&s>o&&s<=r)return!0;if(r>o&&s>o&&s>r)return!1;if(!e.getMeta("paste"))return!1;const n=e.selection.$head.pos,i=n-(s-o),d=n;e.deleteRange(i,d);return!(this.storage.characters({node:e.doc})>o)}})]}}),e.create({name:"dropCursor",addOptions:()=>({color:"currentColor",width:1,class:void 0}),addProseMirrorPlugins(){return[d(this.options)]}}),e.create({name:"focus",addOptions:()=>({className:"has-focus",mode:"all"}),addProseMirrorPlugins(){return[new n({key:new i("focus"),props:{decorations:e=>{let{doc:t,selection:o}=e;const{isEditable:r,isFocused:s}=this.editor,{anchor:n}=o,i=[];if(!r||!s)return a.create(t,[]);let d=0;"deepest"===this.options.mode&&t.descendants((e,t)=>{if(e.isText)return;if(!(n>=t&&n<=t+e.nodeSize-1))return!1;d+=1});let l=0;return t.descendants((e,t)=>{if(e.isText)return!1;if(!(n>=t&&n<=t+e.nodeSize-1))return!1;l+=1;if("deepest"===this.options.mode&&d-l>0||"shallowest"===this.options.mode&&l>1)return"deepest"===this.options.mode;i.push(c.node(t,t+e.nodeSize,{class:this.options.className}))}),a.create(t,i)}}})]}}),e.create({name:"gapCursor",addProseMirrorPlugins:()=>[l()],extendNodeSchema(e){var r;const s={name:e.name,options:e.options,storage:e.storage};return{allowGapCursor:null!=(r=t(o(e,"allowGapCursor",s)))?r:null}}});var m="placeholder";function f(e){return e.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9-]/g,"").replace(/^[0-9-]+/,"").replace(/^-+/,"").toLowerCase()}var g=e.create({name:"placeholder",addOptions:()=>({emptyEditorClass:"is-editor-empty",emptyNodeClass:"is-empty",dataAttribute:m,placeholder:"Write something …",showOnlyWhenEditable:!0,showOnlyCurrent:!0,includeChildren:!1}),addProseMirrorPlugins(){const e=this.options.dataAttribute?`data-${f(this.options.dataAttribute)}`:`data-${m}`;return[new n({key:new i("placeholder"),props:{decorations:t=>{let{doc:o,selection:s}=t;const n=this.editor.isEditable||!this.options.showOnlyWhenEditable,{anchor:i}=s,d=[];if(!n)return null;const l=this.editor.isEmpty;return o.descendants((t,o)=>{const s=i>=o&&i<=o+t.nodeSize,n=!t.isLeaf&&r(t);if((s||!this.options.showOnlyCurrent)&&n){const r=[this.options.emptyNodeClass];l&&r.push(this.options.emptyEditorClass);const n=c.node(o,o+t.nodeSize,{class:r.join(" "),[e]:"function"==typeof this.options.placeholder?this.options.placeholder({editor:this.editor,node:t,pos:o,hasAnchor:s}):this.options.placeholder});d.push(n)}return this.options.includeChildren}),a.create(o,d)}}})]}});function y(e){let{types:t,node:o}=e;return o&&Array.isArray(t)&&t.includes(o.type)||(null==o?void 0:o.type)===t}e.create({name:"selection",addOptions:()=>({className:"selection"}),addProseMirrorPlugins(){const{editor:e,options:t}=this;return[new n({key:new i("selection"),props:{decorations:o=>o.selection.empty||e.isFocused||!e.isEditable||s(o.selection)||e.view.dragging?null:a.create(o.doc,[c.inline(o.selection.from,o.selection.to,{class:t.className})])}})]}}),e.create({name:"trailingNode",addOptions:()=>({node:void 0,notAfter:[]}),addProseMirrorPlugins(){var e;const t=new i(this.name),o=this.options.node||(null==(e=this.editor.schema.topNodeType.contentMatch.defaultType)?void 0:e.name)||"paragraph",r=Object.entries(this.editor.schema.nodes).map(e=>{let[,t]=e;return t}).filter(e=>(this.options.notAfter||[]).concat(o).includes(e.name));return[new n({key:t,appendTransaction:(e,r,s)=>{const{doc:n,tr:i,schema:d}=s,a=t.getState(s),c=n.content.size,l=d.nodes[o];if(a)return i.insert(c,l.create())},state:{init:(e,t)=>!y({node:t.tr.doc.lastChild,types:r}),apply:(e,t)=>{if(!e.docChanged)return t;if(e.getMeta("__uniqueIDTransaction"))return t;return!y({node:e.doc.lastChild,types:r})}}})]}}),e.create({name:"undoRedo",addOptions:()=>({depth:100,newGroupDelay:500}),addCommands:()=>({undo:()=>e=>{let{state:t,dispatch:o}=e;return h(t,o)},redo:()=>e=>{let{state:t,dispatch:o}=e;return u(t,o)}}),addProseMirrorPlugins(){return[p(this.options)]},addKeyboardShortcuts(){return{"Mod-z":()=>this.editor.commands.undo(),"Shift-Mod-z":()=>this.editor.commands.redo(),"Mod-y":()=>this.editor.commands.redo(),"Mod-я":()=>this.editor.commands.undo(),"Shift-Mod-я":()=>this.editor.commands.redo()}}});export{g as Placeholder,f as preparePlaceholderAttribute};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../../../../../../../node_modules/.pnpm/@tiptap+extensions@3.19.0_@tiptap+core@3.19.0_@tiptap+pm@3.20.5__@tiptap+pm@3.20.5/node_modules/@tiptap/extensions/dist/index.js"],"sourcesContent":["// src/character-count/character-count.ts\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nvar CharacterCount = Extension.create({\n name: \"characterCount\",\n addOptions() {\n return {\n limit: null,\n mode: \"textSize\",\n textCounter: (text) => text.length,\n wordCounter: (text) => text.split(\" \").filter((word) => word !== \"\").length\n };\n },\n addStorage() {\n return {\n characters: () => 0,\n words: () => 0\n };\n },\n onBeforeCreate() {\n this.storage.characters = (options) => {\n const node = (options == null ? void 0 : options.node) || this.editor.state.doc;\n const mode = (options == null ? void 0 : options.mode) || this.options.mode;\n if (mode === \"textSize\") {\n const text = node.textBetween(0, node.content.size, void 0, \" \");\n return this.options.textCounter(text);\n }\n return node.nodeSize;\n };\n this.storage.words = (options) => {\n const node = (options == null ? void 0 : options.node) || this.editor.state.doc;\n const text = node.textBetween(0, node.content.size, \" \", \" \");\n return this.options.wordCounter(text);\n };\n },\n addProseMirrorPlugins() {\n let initialEvaluationDone = false;\n return [\n new Plugin({\n key: new PluginKey(\"characterCount\"),\n appendTransaction: (transactions, oldState, newState) => {\n if (initialEvaluationDone) {\n return;\n }\n const limit = this.options.limit;\n if (limit === null || limit === void 0 || limit === 0) {\n initialEvaluationDone = true;\n return;\n }\n const initialContentSize = this.storage.characters({ node: newState.doc });\n if (initialContentSize > limit) {\n const over = initialContentSize - limit;\n const from = 0;\n const to = over;\n console.warn(\n `[CharacterCount] Initial content exceeded limit of ${limit} characters. Content was automatically trimmed.`\n );\n const tr = newState.tr.deleteRange(from, to);\n initialEvaluationDone = true;\n return tr;\n }\n initialEvaluationDone = true;\n },\n filterTransaction: (transaction, state) => {\n const limit = this.options.limit;\n if (!transaction.docChanged || limit === 0 || limit === null || limit === void 0) {\n return true;\n }\n const oldSize = this.storage.characters({ node: state.doc });\n const newSize = this.storage.characters({ node: transaction.doc });\n if (newSize <= limit) {\n return true;\n }\n if (oldSize > limit && newSize > limit && newSize <= oldSize) {\n return true;\n }\n if (oldSize > limit && newSize > limit && newSize > oldSize) {\n return false;\n }\n const isPaste = transaction.getMeta(\"paste\");\n if (!isPaste) {\n return false;\n }\n const pos = transaction.selection.$head.pos;\n const over = newSize - limit;\n const from = pos - over;\n const to = pos;\n transaction.deleteRange(from, to);\n const updatedSize = this.storage.characters({ node: transaction.doc });\n if (updatedSize > limit) {\n return false;\n }\n return true;\n }\n })\n ];\n }\n});\n\n// src/drop-cursor/drop-cursor.ts\nimport { Extension as Extension2 } from \"@tiptap/core\";\nimport { dropCursor } from \"@tiptap/pm/dropcursor\";\nvar Dropcursor = Extension2.create({\n name: \"dropCursor\",\n addOptions() {\n return {\n color: \"currentColor\",\n width: 1,\n class: void 0\n };\n },\n addProseMirrorPlugins() {\n return [dropCursor(this.options)];\n }\n});\n\n// src/focus/focus.ts\nimport { Extension as Extension3 } from \"@tiptap/core\";\nimport { Plugin as Plugin2, PluginKey as PluginKey2 } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nvar Focus = Extension3.create({\n name: \"focus\",\n addOptions() {\n return {\n className: \"has-focus\",\n mode: \"all\"\n };\n },\n addProseMirrorPlugins() {\n return [\n new Plugin2({\n key: new PluginKey2(\"focus\"),\n props: {\n decorations: ({ doc, selection }) => {\n const { isEditable, isFocused } = this.editor;\n const { anchor } = selection;\n const decorations = [];\n if (!isEditable || !isFocused) {\n return DecorationSet.create(doc, []);\n }\n let maxLevels = 0;\n if (this.options.mode === \"deepest\") {\n doc.descendants((node, pos) => {\n if (node.isText) {\n return;\n }\n const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1;\n if (!isCurrent) {\n return false;\n }\n maxLevels += 1;\n });\n }\n let currentLevel = 0;\n doc.descendants((node, pos) => {\n if (node.isText) {\n return false;\n }\n const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1;\n if (!isCurrent) {\n return false;\n }\n currentLevel += 1;\n const outOfScope = this.options.mode === \"deepest\" && maxLevels - currentLevel > 0 || this.options.mode === \"shallowest\" && currentLevel > 1;\n if (outOfScope) {\n return this.options.mode === \"deepest\";\n }\n decorations.push(\n Decoration.node(pos, pos + node.nodeSize, {\n class: this.options.className\n })\n );\n });\n return DecorationSet.create(doc, decorations);\n }\n }\n })\n ];\n }\n});\n\n// src/gap-cursor/gap-cursor.ts\nimport { callOrReturn, Extension as Extension4, getExtensionField } from \"@tiptap/core\";\nimport { gapCursor } from \"@tiptap/pm/gapcursor\";\nvar Gapcursor = Extension4.create({\n name: \"gapCursor\",\n addProseMirrorPlugins() {\n return [gapCursor()];\n },\n extendNodeSchema(extension) {\n var _a;\n const context = {\n name: extension.name,\n options: extension.options,\n storage: extension.storage\n };\n return {\n allowGapCursor: (_a = callOrReturn(getExtensionField(extension, \"allowGapCursor\", context))) != null ? _a : null\n };\n }\n});\n\n// src/placeholder/placeholder.ts\nimport { Extension as Extension5, isNodeEmpty } from \"@tiptap/core\";\nimport { Plugin as Plugin3, PluginKey as PluginKey3 } from \"@tiptap/pm/state\";\nimport { Decoration as Decoration2, DecorationSet as DecorationSet2 } from \"@tiptap/pm/view\";\nvar DEFAULT_DATA_ATTRIBUTE = \"placeholder\";\nfunction preparePlaceholderAttribute(attr) {\n return attr.replace(/\\s+/g, \"-\").replace(/[^a-zA-Z0-9-]/g, \"\").replace(/^[0-9-]+/, \"\").replace(/^-+/, \"\").toLowerCase();\n}\nvar Placeholder = Extension5.create({\n name: \"placeholder\",\n addOptions() {\n return {\n emptyEditorClass: \"is-editor-empty\",\n emptyNodeClass: \"is-empty\",\n dataAttribute: DEFAULT_DATA_ATTRIBUTE,\n placeholder: \"Write something \\u2026\",\n showOnlyWhenEditable: true,\n showOnlyCurrent: true,\n includeChildren: false\n };\n },\n addProseMirrorPlugins() {\n const dataAttribute = this.options.dataAttribute ? `data-${preparePlaceholderAttribute(this.options.dataAttribute)}` : `data-${DEFAULT_DATA_ATTRIBUTE}`;\n return [\n new Plugin3({\n key: new PluginKey3(\"placeholder\"),\n props: {\n decorations: ({ doc, selection }) => {\n const active = this.editor.isEditable || !this.options.showOnlyWhenEditable;\n const { anchor } = selection;\n const decorations = [];\n if (!active) {\n return null;\n }\n const isEmptyDoc = this.editor.isEmpty;\n doc.descendants((node, pos) => {\n const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;\n const isEmpty = !node.isLeaf && isNodeEmpty(node);\n if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {\n const classes = [this.options.emptyNodeClass];\n if (isEmptyDoc) {\n classes.push(this.options.emptyEditorClass);\n }\n const decoration = Decoration2.node(pos, pos + node.nodeSize, {\n class: classes.join(\" \"),\n [dataAttribute]: typeof this.options.placeholder === \"function\" ? this.options.placeholder({\n editor: this.editor,\n node,\n pos,\n hasAnchor\n }) : this.options.placeholder\n });\n decorations.push(decoration);\n }\n return this.options.includeChildren;\n });\n return DecorationSet2.create(doc, decorations);\n }\n }\n })\n ];\n }\n});\n\n// src/selection/selection.ts\nimport { Extension as Extension6, isNodeSelection } from \"@tiptap/core\";\nimport { Plugin as Plugin4, PluginKey as PluginKey4 } from \"@tiptap/pm/state\";\nimport { Decoration as Decoration3, DecorationSet as DecorationSet3 } from \"@tiptap/pm/view\";\nvar Selection = Extension6.create({\n name: \"selection\",\n addOptions() {\n return {\n className: \"selection\"\n };\n },\n addProseMirrorPlugins() {\n const { editor, options } = this;\n return [\n new Plugin4({\n key: new PluginKey4(\"selection\"),\n props: {\n decorations(state) {\n if (state.selection.empty || editor.isFocused || !editor.isEditable || isNodeSelection(state.selection) || editor.view.dragging) {\n return null;\n }\n return DecorationSet3.create(state.doc, [\n Decoration3.inline(state.selection.from, state.selection.to, {\n class: options.className\n })\n ]);\n }\n }\n })\n ];\n }\n});\n\n// src/trailing-node/trailing-node.ts\nimport { Extension as Extension7 } from \"@tiptap/core\";\nimport { Plugin as Plugin5, PluginKey as PluginKey5 } from \"@tiptap/pm/state\";\nfunction nodeEqualsType({ types, node }) {\n return node && Array.isArray(types) && types.includes(node.type) || (node == null ? void 0 : node.type) === types;\n}\nvar TrailingNode = Extension7.create({\n name: \"trailingNode\",\n addOptions() {\n return {\n node: void 0,\n notAfter: []\n };\n },\n addProseMirrorPlugins() {\n var _a;\n const plugin = new PluginKey5(this.name);\n const defaultNode = this.options.node || ((_a = this.editor.schema.topNodeType.contentMatch.defaultType) == null ? void 0 : _a.name) || \"paragraph\";\n const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter((node) => (this.options.notAfter || []).concat(defaultNode).includes(node.name));\n return [\n new Plugin5({\n key: plugin,\n appendTransaction: (_, __, state) => {\n const { doc, tr, schema } = state;\n const shouldInsertNodeAtEnd = plugin.getState(state);\n const endPosition = doc.content.size;\n const type = schema.nodes[defaultNode];\n if (!shouldInsertNodeAtEnd) {\n return;\n }\n return tr.insert(endPosition, type.create());\n },\n state: {\n init: (_, state) => {\n const lastNode = state.tr.doc.lastChild;\n return !nodeEqualsType({ node: lastNode, types: disabledNodes });\n },\n apply: (tr, value) => {\n if (!tr.docChanged) {\n return value;\n }\n if (tr.getMeta(\"__uniqueIDTransaction\")) {\n return value;\n }\n const lastNode = tr.doc.lastChild;\n return !nodeEqualsType({ node: lastNode, types: disabledNodes });\n }\n }\n })\n ];\n }\n});\n\n// src/undo-redo/undo-redo.ts\nimport { Extension as Extension8 } from \"@tiptap/core\";\nimport { history, redo, undo } from \"@tiptap/pm/history\";\nvar UndoRedo = Extension8.create({\n name: \"undoRedo\",\n addOptions() {\n return {\n depth: 100,\n newGroupDelay: 500\n };\n },\n addCommands() {\n return {\n undo: () => ({ state, dispatch }) => {\n return undo(state, dispatch);\n },\n redo: () => ({ state, dispatch }) => {\n return redo(state, dispatch);\n }\n };\n },\n addProseMirrorPlugins() {\n return [history(this.options)];\n },\n addKeyboardShortcuts() {\n return {\n \"Mod-z\": () => this.editor.commands.undo(),\n \"Shift-Mod-z\": () => this.editor.commands.redo(),\n \"Mod-y\": () => this.editor.commands.redo(),\n // Russian keyboard layouts\n \"Mod-\\u044F\": () => this.editor.commands.undo(),\n \"Shift-Mod-\\u044F\": () => this.editor.commands.redo()\n };\n }\n});\nexport {\n CharacterCount,\n Dropcursor,\n Focus,\n Gapcursor,\n Placeholder,\n Selection,\n TrailingNode,\n UndoRedo,\n preparePlaceholderAttribute\n};\n//# sourceMappingURL=index.js.map"],"names":["Extension","create","name","addOptions","limit","mode","textCounter","text","length","wordCounter","split","filter","word","addStorage","characters","words","onBeforeCreate","this","storage","options","node","editor","state","doc","textBetween","content","size","nodeSize","addProseMirrorPlugins","initialEvaluationDone","Plugin","key","PluginKey","appendTransaction","transactions","oldState","newState","initialContentSize","from","to","tr","deleteRange","filterTransaction","transaction","docChanged","oldSize","newSize","getMeta","pos","selection","$head"],"mappings":"qvBA2D8BA,EAAUC,OAAqD,CAC3FC,KAAM,iBAENC,WAAAA,KACS,CACLC,MAAO,KACPC,KAAM,WACNC,YAAaC,GAAQA,EAAKC,OAC1BC,YAAaF,GAAQA,EAAKG,MAAM,KAAKC,OAAOC,GAAiB,KAATA,GAAaJ,SAIrEK,WAAAA,KACS,CACLC,WAAYA,IAAM,EAClBC,MAAOA,IAAM,IAIjBC,cAAAA,GACEC,KAAKC,QAAQJ,WAAaK,IACxB,MAAMC,GAAO,MAAAD,OAAA,EAAAA,EAASC,OAAQH,KAAKI,OAAOC,MAAMC,IAGhD,GAAa,eAFA,MAAAJ,OAAA,EAAAA,EAASd,OAAQY,KAAKE,QAAQd,MAElB,CACvB,MAAME,EAAOa,EAAKI,YAAY,EAAGJ,EAAKK,QAAQC,UAAM,EAAW,KAE/D,OAAOT,KAAKE,QAAQb,YAAYC,EAClC,CAEA,OAAOa,EAAKO,UAGdV,KAAKC,QAAQH,MAAQI,IACnB,MAAMC,GAAO,MAAAD,OAAA,EAAAA,EAASC,OAAQH,KAAKI,OAAOC,MAAMC,IAC1ChB,EAAOa,EAAKI,YAAY,EAAGJ,EAAKK,QAAQC,KAAM,IAAK,KAEzD,OAAOT,KAAKE,QAAQV,YAAYF,GAEpC,EAEAqB,qBAAAA,GACE,IAAIC,GAAwB,EAE5B,MAAO,CACL,IAAIC,EAAO,CACTC,IAAK,IAAIC,EAAU,kBACnBC,kBAAmBA,CAACC,EAAcC,EAAUC,KAC1C,GAAIP,EACF,OAGF,MAAMzB,EAAQa,KAAKE,QAAQf,MAE3B,GAAIA,SAAmD,IAAVA,EAE3C,YADAyB,GAAwB,GAI1B,MAAMQ,EAAqBpB,KAAKC,QAAQJ,WAAW,CAAEM,KAAMgB,EAASb,MAEpE,GAAIc,EAAqBjC,EAAO,CAC9B,MACMkC,EAAO,EACPC,EAFOF,EAAqBjC,EAO5BoC,EAAKJ,EAASI,GAAGC,YAAYH,EAAMC,GAGzC,OADAV,GAAwB,EACjBW,CACT,CAEAX,GAAwB,GAE1Ba,kBAAmBA,CAACC,EAAarB,KAC/B,MAAMlB,EAAQa,KAAKE,QAAQf,MAG3B,IAAKuC,EAAYC,YAAwB,IAAVxC,GAA3B,MAA0CA,EAC5C,OAAO,EAGT,MAAMyC,EAAU5B,KAAKC,QAAQJ,WAAW,CAAEM,KAAME,EAAMC,MAChDuB,EAAU7B,KAAKC,QAAQJ,WAAW,CAAEM,KAAMuB,EAAYpB,MAG5D,GAAIuB,GAAW1C,EACb,OAAO,EAIT,GAAIyC,EAAUzC,GAAS0C,EAAU1C,GAAS0C,GAAWD,EACnD,OAAO,EAIT,GAAIA,EAAUzC,GAAS0C,EAAU1C,GAAS0C,EAAUD,EAClD,OAAO,EAMT,IAHgBF,EAAYI,QAAQ,SAIlC,OAAO,EAIT,MAAMC,EAAML,EAAYM,UAAUC,MAAMF,IAElCV,EAAOU,GADAF,EAAU1C,GAEjBmC,EAAKS,EAIXL,EAAYF,YAAYH,EAAMC,GAQ9B,QAFoBtB,KAAKC,QAAQJ,WAAW,CAAEM,KAAMuB,EAAYpB,MAE9CnB,MAQ1B","x_google_ignoreList":[0]}
|
package/es/subject/action.mjs
CHANGED
|
@@ -62,8 +62,8 @@ import{html as e,css as t,LitElement as o}from"lit";import{property as r}from"..
|
|
|
62
62
|
:host { display: block; font-family: system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif; font-size: 12px; }
|
|
63
63
|
*, ::before, ::after { box-sizing: border-box; }
|
|
64
64
|
|
|
65
|
-
.action { display: flex; justify-content: space-between; align-items: center; padding: 10px 12px; flex-wrap: wrap; gap: 8px;
|
|
66
|
-
.action.active { background
|
|
65
|
+
.action { display: flex; justify-content: space-between; align-items: center; padding: 10px 12px; flex-wrap: wrap; gap: 8px; }
|
|
66
|
+
.action.active { background: transparent; }
|
|
67
67
|
.left { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
68
68
|
.right { display: flex; align-items: center; gap: 4px; }
|
|
69
69
|
|