import { Marked } from "marked" import { cursors, Cursor } from "./cursor" // 示例 Markdown 文本 const markdown = ` # 2333 - [ ] 1111 - [ ] 1111 - [ ] 1111 - [x] 2222 - [ ] 233323 - [ ] 233323 - [ ] 233323 这是一段测试文本 ` const marked = new Marked() const tokens = marked.lexer(markdown) // 创建 textarea 接受输入 const textarea = document.createElement("textarea") Object.assign(textarea.style, { position: "fixed", bottom: "10px", left: "10px", width: "300px", height: "100px", zIndex: "1000", placeholder: "在这里输入文本或使用方向键调整位置", }) document.body.appendChild(textarea) // 处理输入事件 textarea.oninput = () => { cursors.forEach(cursor => cursor.oninput(textarea)) textarea.value = "" } // 处理方向键移动插入点 textarea.onkeydown = (event) => { cursors.forEach(cursor => cursor.onkeydown({ key: event.key })) } // 渲染 Markdown 并监听点击事件 const element = document.createElement("div") element.innerHTML = marked.parser(tokens) document.body.appendChild(element) // 点击事件:记录插入位置 element.onclick = (event) => { if (event.target.tagName !== "LI") return const { clientX: x, clientY: y } = event // 查找点击的文本节点 const textNodes = Array.from(event.target.childNodes).filter( (node) => node.nodeType === Node.TEXT_NODE ) const targetNode = textNodes.find((node) => { const range = document.createRange() range.selectNodeContents(node) const rect = range.getBoundingClientRect() return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom }) if (!targetNode) return // 计算插入位置索引 const positions = [...targetNode.textContent].map((_, i) => { const range = document.createRange() range.setStart(targetNode, i) range.setEnd(targetNode, i + 1) return { index: i, rect: range.getBoundingClientRect() } }) const closest = positions.reduce((closest, pos) => { const dist = Math.abs(x - pos.rect.left) return dist < closest.distance ? { ...pos, distance: dist } : closest }, { index: -1, distance: Infinity }) const rect = closest.rect const insertBefore = x < rect.left + rect.width / 2 const insertIndex = closest.index + (insertBefore ? 0 : 1) // 设置光标的目标节点和插入位置 cursors.forEach(cursor => cursor.setTarget(targetNode, insertIndex)) // 如果是点击多个光标的情况,增加新光标 if (event.ctrlKey || !cursors.length) { const newCursor = new Cursor(targetNode, insertIndex) cursors.push(newCursor) console.log("新增光标") } // 更新光标位置 cursors.forEach(cursor => cursor.updatePosition(cursor.getBoundingClientRect())) // 聚焦输入框 textarea.value = "" textarea.focus() }