fix(editor): use manual input prompt instead of window.prompt
continuous-integration/drone/push Build is passing Details

Resolves vikunja/desktop#184
This commit is contained in:
kolaente 2024-01-21 20:08:10 +01:00
parent 8ea97f3ffc
commit 57c99a22a0
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
4 changed files with 76 additions and 54 deletions

View File

@ -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>

View File

@ -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) {

View 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()
}

View 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()
})
})
}