fix: context menu bug and incorrect position (#3874)
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
ref="contextMenuRef"
|
ref="contextMenuRef"
|
||||||
class="fixed translate-y-8 transform rounded border border-dividerDark bg-popover p-2 shadow-lg"
|
class="fixed transform -translate-x-10 -translate-y-8 rounded border border-dividerDark bg-popover p-2 shadow-lg"
|
||||||
:style="`top: ${position.top}px; left: ${position.left}px; z-index: 1000;`"
|
:style="`top: ${position.top}px; left: ${position.left}px; z-index: 100;`"
|
||||||
>
|
>
|
||||||
<div v-if="contextMenuOptions" class="flex flex-col">
|
<div v-if="contextMenuOptions" class="flex flex-col">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -417,7 +417,9 @@ function handleTextSelection() {
|
|||||||
const { from, to } = selection
|
const { from, to } = selection
|
||||||
if (from === to) return
|
if (from === to) return
|
||||||
const text = view.value?.state.doc.sliceString(from, to)
|
const text = view.value?.state.doc.sliceString(from, to)
|
||||||
const { top, left } = view.value?.coordsAtPos(from)
|
const coords = view.value?.coordsAtPos(from)
|
||||||
|
const top = coords?.top ?? 0
|
||||||
|
const left = coords?.left ?? 0
|
||||||
if (text) {
|
if (text) {
|
||||||
invokeAction("contextmenu.open", {
|
invokeAction("contextmenu.open", {
|
||||||
position: {
|
position: {
|
||||||
@@ -439,16 +441,17 @@ function handleTextSelection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const initView = (el: any) => {
|
|
||||||
// Debounce to prevent double click from selecting the word
|
// Debounce to prevent double click from selecting the word
|
||||||
const debounceFn = useDebounceFn(() => {
|
const debouncedTextSelection = (time: number) =>
|
||||||
|
useDebounceFn(() => {
|
||||||
handleTextSelection()
|
handleTextSelection()
|
||||||
}, 140)
|
}, time)
|
||||||
|
|
||||||
|
const initView = (el: any) => {
|
||||||
// Only add event listeners if context menu is enabled in the component
|
// Only add event listeners if context menu is enabled in the component
|
||||||
if (props.contextMenuEnabled) {
|
if (props.contextMenuEnabled) {
|
||||||
el.addEventListener("mouseup", debounceFn)
|
el.addEventListener("mouseup", debouncedTextSelection(140))
|
||||||
el.addEventListener("keyup", debounceFn)
|
el.addEventListener("keyup", debouncedTextSelection(140))
|
||||||
}
|
}
|
||||||
|
|
||||||
const extensions: Extension = getExtensions(props.readonly || isSecret.value)
|
const extensions: Extension = getExtensions(props.readonly || isSecret.value)
|
||||||
@@ -498,7 +501,8 @@ const getExtensions = (readonly: boolean): Extension => {
|
|||||||
},
|
},
|
||||||
scroll(event) {
|
scroll(event) {
|
||||||
if (event.target && props.contextMenuEnabled) {
|
if (event.target && props.contextMenuEnabled) {
|
||||||
handleTextSelection()
|
// Debounce to make the performance better
|
||||||
|
debouncedTextSelection(30)()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -242,7 +242,9 @@ export function useCodemirror(
|
|||||||
const { from, to } = selection
|
const { from, to } = selection
|
||||||
if (from === to) return
|
if (from === to) return
|
||||||
const text = view.value?.state.doc.sliceString(from, to)
|
const text = view.value?.state.doc.sliceString(from, to)
|
||||||
const { top, left } = view.value?.coordsAtPos(from)
|
const coords = view.value?.coordsAtPos(from)
|
||||||
|
const top = coords?.top ?? 0
|
||||||
|
const left = coords?.left ?? 0
|
||||||
if (text?.trim()) {
|
if (text?.trim()) {
|
||||||
invokeAction("contextmenu.open", {
|
invokeAction("contextmenu.open", {
|
||||||
position: {
|
position: {
|
||||||
@@ -263,6 +265,12 @@ export function useCodemirror(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debounce to prevent double click from selecting the word
|
||||||
|
const debouncedTextSelection = (time: number) =>
|
||||||
|
useDebounceFn(() => {
|
||||||
|
handleTextSelection()
|
||||||
|
}, time)
|
||||||
|
|
||||||
const initView = (el: any) => {
|
const initView = (el: any) => {
|
||||||
if (el) platform.ui?.onCodemirrorInstanceMount?.(el)
|
if (el) platform.ui?.onCodemirrorInstanceMount?.(el)
|
||||||
|
|
||||||
@@ -274,15 +282,10 @@ export function useCodemirror(
|
|||||||
ViewPlugin.fromClass(
|
ViewPlugin.fromClass(
|
||||||
class {
|
class {
|
||||||
update(update: ViewUpdate) {
|
update(update: ViewUpdate) {
|
||||||
// Debounce to prevent double click from selecting the word
|
|
||||||
const debounceFn = useDebounceFn(() => {
|
|
||||||
handleTextSelection()
|
|
||||||
}, 140)
|
|
||||||
|
|
||||||
// Only add event listeners if context menu is enabled in the editor
|
// Only add event listeners if context menu is enabled in the editor
|
||||||
if (options.contextMenuEnabled) {
|
if (options.contextMenuEnabled) {
|
||||||
el.addEventListener("mouseup", debounceFn)
|
el.addEventListener("mouseup", debouncedTextSelection(140))
|
||||||
el.addEventListener("keyup", debounceFn)
|
el.addEventListener("keyup", debouncedTextSelection(140))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.onUpdate) {
|
if (options.onUpdate) {
|
||||||
@@ -324,7 +327,8 @@ export function useCodemirror(
|
|||||||
EditorView.domEventHandlers({
|
EditorView.domEventHandlers({
|
||||||
scroll(event) {
|
scroll(event) {
|
||||||
if (event.target && options.contextMenuEnabled) {
|
if (event.target && options.contextMenuEnabled) {
|
||||||
handleTextSelection()
|
// Debounce to make the performance better
|
||||||
|
debouncedTextSelection(30)()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user