fix(editor): use manual input prompt instead of window.prompt
Resolves https://kolaente.dev/vikunja/desktop/issues/184
This commit is contained in:
parent
8ea97f3ffc
commit
57c99a22a0
@ -336,6 +336,7 @@ import {ref} from 'vue'
|
||||
import {Editor} from '@tiptap/vue-3'
|
||||
|
||||
import BaseButton from '@/components/base/BaseButton.vue'
|
||||
import {setLinkInEditor} from '@/components/input/editor/setLinkInEditor'
|
||||
|
||||
const {
|
||||
editor = null,
|
||||
@ -353,29 +354,8 @@ function openImagePicker() {
|
||||
document.getElementById('tiptap__image-upload').click()
|
||||
}
|
||||
|
||||
function setLink() {
|
||||
const previousUrl = editor.getAttributes('link').href
|
||||
const url = window.prompt('URL', previousUrl)
|
||||
|
||||
// cancelled
|
||||
if (url === null) {
|
||||
return
|
||||
}
|
||||
|
||||
// empty
|
||||
if (url === '') {
|
||||
editor.chain().focus().extendMarkRange('link').unsetLink().run()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// update link
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.extendMarkRange('link')
|
||||
.setLink({href: url, target: '_blank'})
|
||||
.run()
|
||||
function setLink(event) {
|
||||
setLinkInEditor(event.target.getBoundingClientRect(), editor)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -174,6 +174,8 @@ import {Placeholder} from '@tiptap/extension-placeholder'
|
||||
import {eventToHotkeyString} from '@github/hotkey'
|
||||
import {mergeAttributes} from '@tiptap/core'
|
||||
import {isEditorContentEmpty} from '@/helpers/editorContentEmpty'
|
||||
import inputPrompt from '@/helpers/inputPrompt'
|
||||
import {setLinkInEditor} from '@/components/input/editor/setLinkInEditor'
|
||||
|
||||
const tiptapInstanceRef = ref<HTMLInputElement | null>(null)
|
||||
|
||||
@ -320,7 +322,7 @@ const editor = useEditor({
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
'Mod-Enter': () => {
|
||||
if(contentHasChanged.value) {
|
||||
if (contentHasChanged.value) {
|
||||
bubbleSave()
|
||||
}
|
||||
},
|
||||
@ -470,7 +472,7 @@ function uploadAndInsertFiles(files: File[] | FileList) {
|
||||
})
|
||||
}
|
||||
|
||||
function addImage() {
|
||||
async function addImage(event) {
|
||||
|
||||
if (typeof uploadCallback !== 'undefined') {
|
||||
const files = uploadInputRef.value?.files
|
||||
@ -484,7 +486,7 @@ function addImage() {
|
||||
return
|
||||
}
|
||||
|
||||
const url = window.prompt('URL')
|
||||
const url = await inputPrompt(event.target.getBoundingClientRect())
|
||||
|
||||
if (url) {
|
||||
editor.value?.chain().focus().setImage({src: url}).run()
|
||||
@ -492,34 +494,8 @@ function addImage() {
|
||||
}
|
||||
}
|
||||
|
||||
function setLink() {
|
||||
const previousUrl = editor.value?.getAttributes('link').href
|
||||
const url = window.prompt('URL', previousUrl)
|
||||
|
||||
// cancelled
|
||||
if (url === null) {
|
||||
return
|
||||
}
|
||||
|
||||
// empty
|
||||
if (url === '') {
|
||||
editor.value
|
||||
?.chain()
|
||||
.focus()
|
||||
.extendMarkRange('link')
|
||||
.unsetLink()
|
||||
.run()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// update link
|
||||
editor.value
|
||||
?.chain()
|
||||
.focus()
|
||||
.extendMarkRange('link')
|
||||
.setLink({href: url, target: '_blank'})
|
||||
.run()
|
||||
function setLink(event) {
|
||||
setLinkInEditor(event.target.getBoundingClientRect(), editor.value)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@ -573,6 +549,7 @@ function setFocusToEditor(event) {
|
||||
event.target.contentEditable === 'true') {
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
if (!isEditing.value && isEditEnabled) {
|
||||
|
26
src/components/input/editor/setLinkInEditor.ts
Normal file
26
src/components/input/editor/setLinkInEditor.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import inputPrompt from '@/helpers/inputPrompt'
|
||||
|
||||
export async function setLinkInEditor(pos, editor) {
|
||||
const previousUrl = editor?.getAttributes('link').href || ''
|
||||
const url = await inputPrompt(pos, previousUrl)
|
||||
|
||||
// empty
|
||||
if (url === '') {
|
||||
editor
|
||||
?.chain()
|
||||
.focus()
|
||||
.extendMarkRange('link')
|
||||
.unsetLink()
|
||||
.run()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// update link
|
||||
editor
|
||||
?.chain()
|
||||
.focus()
|
||||
.extendMarkRange('link')
|
||||
.setLink({href: url, target: '_blank'})
|
||||
.run()
|
||||
}
|
39
src/helpers/inputPrompt.ts
Normal file
39
src/helpers/inputPrompt.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import {createRandomID} from '@/helpers/randomId'
|
||||
import tippy from 'tippy.js'
|
||||
import {nextTick} from 'vue'
|
||||
import {eventToHotkeyString} from '@github/hotkey'
|
||||
|
||||
export default function inputPrompt(pos: ClientRect, oldValue: string = ''): Promise<string> {
|
||||
return new Promise((resolve) => {
|
||||
const id = 'link-input-' + createRandomID()
|
||||
|
||||
const linkPopup = tippy('body', {
|
||||
getReferenceClientRect: () => pos,
|
||||
appendTo: () => document.body,
|
||||
content: `<div><input class="input" placeholder="URL" id="${id}" value="${oldValue}"/></div>`,
|
||||
showOnCreate: true,
|
||||
interactive: true,
|
||||
trigger: 'manual',
|
||||
placement: 'top-start',
|
||||
allowHTML: true,
|
||||
})
|
||||
|
||||
linkPopup[0].show()
|
||||
|
||||
nextTick(() => document.getElementById(id)?.focus())
|
||||
|
||||
document.getElementById(id)?.addEventListener('keydown', event => {
|
||||
const hotkeyString = eventToHotkeyString(event)
|
||||
if (hotkeyString !== 'Enter') {
|
||||
return
|
||||
}
|
||||
|
||||
const url = event.target.value
|
||||
|
||||
resolve(url)
|
||||
|
||||
linkPopup[0].hide()
|
||||
})
|
||||
|
||||
})
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user