|
@@ -223,8 +223,87 @@ const handleInput = (e) => {
|
|
|
newSelection.addRange(newRange)
|
|
|
}
|
|
|
state.textCount = e.target.innerText?.trim().length || 0
|
|
|
+ isSlashBeforeCursorEnhanced()
|
|
|
emitValue()
|
|
|
}
|
|
|
+function isSlashBeforeCursorEnhanced() {
|
|
|
+ const selection = window.getSelection()
|
|
|
+ if (selection.rangeCount === 0) return false
|
|
|
+
|
|
|
+ const range = selection.getRangeAt(0)
|
|
|
+ let node = range.startContainer
|
|
|
+ let offset = range.startOffset
|
|
|
+
|
|
|
+ // 如果当前节点不是文本节点,尝试找到前一个文本节点
|
|
|
+ if (node.nodeType !== Node.TEXT_NODE) {
|
|
|
+ // 如果光标在元素开始处,需要查找前一个兄弟节点
|
|
|
+ if (offset === 0) {
|
|
|
+ let prevNode = getPreviousTextNode(node)
|
|
|
+ if (!prevNode) return false
|
|
|
+ node = prevNode
|
|
|
+ offset = node.textContent.length
|
|
|
+ } else {
|
|
|
+ // 光标在元素中间,需要检查子节点
|
|
|
+ const child = node.childNodes[offset - 1]
|
|
|
+ const lastTextNode = getLastTextNode(child)
|
|
|
+ if (!lastTextNode) return false
|
|
|
+ node = lastTextNode
|
|
|
+ offset = node.textContent.length
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查前一个字符是否是/
|
|
|
+ if (offset > 0) {
|
|
|
+ if (node.textContent[offset - 1] === '/') {
|
|
|
+ showVariablePopup(range)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果当前文本节点开头,需要检查前一个文本节点
|
|
|
+ const prevTextNode = getPreviousTextNode(node)
|
|
|
+ if (prevTextNode && prevTextNode.textContent.length > 0) {
|
|
|
+ if (prevTextNode.textContent[prevTextNode.textContent.length - 1] === '/') {
|
|
|
+ showVariablePopup(range)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ state.showVariableList = false
|
|
|
+}
|
|
|
+// 辅助函数:获取前一个文本节点
|
|
|
+function getPreviousTextNode(node) {
|
|
|
+ let sibling = node.previousSibling
|
|
|
+ while (sibling) {
|
|
|
+ if (
|
|
|
+ sibling.nodeType === Node.TEXT_NODE &&
|
|
|
+ sibling.textContent.trim() !== ''
|
|
|
+ ) {
|
|
|
+ return sibling
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ sibling.nodeType === Node.ELEMENT_NODE &&
|
|
|
+ sibling.childNodes.length > 0
|
|
|
+ ) {
|
|
|
+ const lastChild = getLastTextNode(sibling)
|
|
|
+ if (lastChild) return lastChild
|
|
|
+ }
|
|
|
+ sibling = sibling.previousSibling
|
|
|
+ }
|
|
|
+ return node.parentNode ? getPreviousTextNode(node.parentNode) : null
|
|
|
+}
|
|
|
+
|
|
|
+// 辅助函数:获取最后一个文本节点
|
|
|
+function getLastTextNode(node) {
|
|
|
+ if (node.nodeType === Node.TEXT_NODE) return node
|
|
|
+ if (node.nodeType === Node.ELEMENT_NODE && node.childNodes.length > 0) {
|
|
|
+ for (let i = node.childNodes.length - 1; i >= 0; i--) {
|
|
|
+ const result = getLastTextNode(node.childNodes[i])
|
|
|
+ if (result) return result
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null
|
|
|
+}
|
|
|
const handlePaste = (e) => {
|
|
|
e.preventDefault()
|
|
|
const text = (e.clipboardData || window.clipboardData).getData('text')
|
|
@@ -250,13 +329,32 @@ const initVarsDom = (vars) => {
|
|
|
return dom
|
|
|
}
|
|
|
const setVars = (vars) => {
|
|
|
- state.showVariableList = false
|
|
|
const nodeToInsert: any = initVarsDom(vars)
|
|
|
// 检查是否有有效的选择范围且在当前容器内
|
|
|
if (state.lastSelection) {
|
|
|
+ if (state.showVariableList) {
|
|
|
+ const range = state.lastSelection.cloneRange()
|
|
|
+ const startContainer = range.startContainer
|
|
|
+ const startOffset = range.startOffset
|
|
|
+
|
|
|
+ if (startContainer.nodeType === Node.TEXT_NODE && startOffset > 0) {
|
|
|
+ const textBefore = startContainer.textContent.slice(0, startOffset)
|
|
|
+ if (textBefore.endsWith('/')) {
|
|
|
+ // Create a new range covering just the '/' character
|
|
|
+ const deleteRange = document.createRange()
|
|
|
+ deleteRange.setStart(startContainer, startOffset - 1)
|
|
|
+ deleteRange.setEnd(startContainer, startOffset)
|
|
|
+ deleteRange.deleteContents()
|
|
|
+
|
|
|
+ // Adjust the original selection position
|
|
|
+ range.setStart(startContainer, startOffset - 1)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
// 恢复选区
|
|
|
const sel: any = window.getSelection()
|
|
|
sel.removeAllRanges()
|
|
|
+ console.log(state.lastSelection)
|
|
|
sel.addRange(state.lastSelection)
|
|
|
|
|
|
// 插入内容
|
|
@@ -271,6 +369,8 @@ const setVars = (vars) => {
|
|
|
// 可选:滚动到插入的元素
|
|
|
nodeToInsert.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
|
|
|
emitValue()
|
|
|
+ state.text = ''
|
|
|
+ state.showVariableList = false
|
|
|
}
|
|
|
const handleSelectionchange = () => {
|
|
|
if (state.isFocus) {
|
|
@@ -304,14 +404,12 @@ const emitValue = () => {
|
|
|
// 显示变量弹窗
|
|
|
const showVariablePopup = (range) => {
|
|
|
const rect = range.getBoundingClientRect()
|
|
|
-
|
|
|
state.variableListStyle = {
|
|
|
position: 'absolute',
|
|
|
left: `${rect.left + window.scrollX}px`,
|
|
|
top: `${rect.bottom + window.scrollY}px`,
|
|
|
zIndex: 1000,
|
|
|
}
|
|
|
-
|
|
|
state.showVariableList = true
|
|
|
}
|
|
|
const onMouseDown = (e) => {
|