|
1 | 1 | <script setup lang="ts"> |
2 | | -import { computed, ref } from 'vue' |
| 2 | +import { computed, onBeforeUnmount, onMounted, ref } from 'vue' |
3 | 3 | import { TinySwitch } from '@opentiny/vue' |
4 | 4 | import { Sender } from '@opentiny/tiny-robot' |
5 | 5 | import type { MentionItem, TemplateItem, SenderSuggestionItem } from '@opentiny/tiny-robot' |
6 | 6 |
|
| 7 | +declare global { |
| 8 | + interface Window { |
| 9 | + __senderTestApi?: { |
| 10 | + moveCursorBeforeTemplate: (index: number) => boolean |
| 11 | + pressDeleteBeforeTemplate: (index: number) => boolean |
| 12 | + } |
| 13 | + } |
| 14 | +} |
| 15 | +
|
7 | 16 | const senderRef = ref() |
8 | 17 | const content = ref('') |
9 | 18 | const result = ref('') |
@@ -157,6 +166,58 @@ const extensions = computed(() => { |
157 | 166 | } |
158 | 167 | return exts |
159 | 168 | }) |
| 169 | +
|
| 170 | +const moveCursorBeforeTemplate = (index: number) => { |
| 171 | + const exposedEditor = senderRef.value?.editor |
| 172 | + const editor = exposedEditor?.value ?? exposedEditor |
| 173 | + if (!editor) return false |
| 174 | +
|
| 175 | + let currentIndex = 0 |
| 176 | + let templatePosition: number | null = null |
| 177 | +
|
| 178 | + editor.state.doc.descendants((node: { type: { name: string } }, pos: number) => { |
| 179 | + if (node.type.name === 'templateBlock') { |
| 180 | + if (currentIndex === index) { |
| 181 | + templatePosition = pos |
| 182 | + return false |
| 183 | + } |
| 184 | + currentIndex += 1 |
| 185 | + } |
| 186 | + return true |
| 187 | + }) |
| 188 | +
|
| 189 | + if (templatePosition === null) return false |
| 190 | +
|
| 191 | + editor.commands.setTextSelection(templatePosition) |
| 192 | + editor.commands.focus(templatePosition) |
| 193 | +
|
| 194 | + return editor.state.selection.$from.nodeAfter?.type?.name === 'templateBlock' |
| 195 | +} |
| 196 | +
|
| 197 | +const pressDeleteBeforeTemplate = (index: number) => { |
| 198 | + const exposedEditor = senderRef.value?.editor |
| 199 | + const editor = exposedEditor?.value ?? exposedEditor |
| 200 | + if (!editor || !moveCursorBeforeTemplate(index)) return false |
| 201 | +
|
| 202 | + const deleteEvent = new KeyboardEvent('keydown', { |
| 203 | + key: 'Delete', |
| 204 | + bubbles: true, |
| 205 | + cancelable: true, |
| 206 | + }) |
| 207 | +
|
| 208 | + return editor.view.dom.dispatchEvent(deleteEvent) === false |
| 209 | +} |
| 210 | +
|
| 211 | +onMounted(() => { |
| 212 | + window.__senderTestApi = { |
| 213 | + moveCursorBeforeTemplate, |
| 214 | + pressDeleteBeforeTemplate, |
| 215 | + } |
| 216 | +}) |
| 217 | +
|
| 218 | +onBeforeUnmount(() => { |
| 219 | + delete window.__senderTestApi |
| 220 | +}) |
160 | 221 | </script> |
161 | 222 |
|
162 | 223 | <template> |
|
0 commit comments