|
|
@ -59,6 +59,10 @@ const isFocused = ref(false) |
|
|
|
|
|
|
|
|
|
|
|
const keys = useMagicKeys() |
|
|
|
const keys = useMagicKeys() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const shouldShowLinkOption = computed(() => { |
|
|
|
|
|
|
|
return isFormField.value ? isFocused.value : true |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const turndownService = new TurndownService({}) |
|
|
|
const turndownService = new TurndownService({}) |
|
|
|
|
|
|
|
|
|
|
|
turndownService.addRule('lineBreak', { |
|
|
|
turndownService.addRule('lineBreak', { |
|
|
@ -133,6 +137,8 @@ marked.use({ extensions: [checkListItem] }) |
|
|
|
|
|
|
|
|
|
|
|
const editorDom = ref<HTMLElement | null>(null) |
|
|
|
const editorDom = ref<HTMLElement | null>(null) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const richTextLinkOptionRef = ref<HTMLElement | null>(null) |
|
|
|
|
|
|
|
|
|
|
|
const vModel = useVModel(props, 'value', emits, { defaultValue: '' }) |
|
|
|
const vModel = useVModel(props, 'value', emits, { defaultValue: '' }) |
|
|
|
|
|
|
|
|
|
|
|
const tiptapExtensions = [ |
|
|
|
const tiptapExtensions = [ |
|
|
@ -167,7 +173,7 @@ const editor = useEditor({ |
|
|
|
emits('focus') |
|
|
|
emits('focus') |
|
|
|
}, |
|
|
|
}, |
|
|
|
onBlur: (e) => { |
|
|
|
onBlur: (e) => { |
|
|
|
if (!(e?.event?.relatedTarget as HTMLElement)?.closest('.bubble-menu, .nc-textarea-rich-editor')) { |
|
|
|
if (!(e?.event?.relatedTarget as HTMLElement)?.closest('.bubble-menu, .nc-textarea-rich-editor, .nc-rich-text')) { |
|
|
|
isFocused.value = false |
|
|
|
isFocused.value = false |
|
|
|
emits('blur') |
|
|
|
emits('blur') |
|
|
|
} |
|
|
|
} |
|
|
@ -239,13 +245,37 @@ useEventListener( |
|
|
|
'focusout', |
|
|
|
'focusout', |
|
|
|
(e: FocusEvent) => { |
|
|
|
(e: FocusEvent) => { |
|
|
|
const targetEl = e?.relatedTarget as HTMLElement |
|
|
|
const targetEl = e?.relatedTarget as HTMLElement |
|
|
|
if (targetEl?.classList?.contains('tiptap') || !targetEl?.closest('.bubble-menu, .nc-textarea-rich-editor')) { |
|
|
|
if (targetEl?.classList?.contains('tiptap') || !targetEl?.closest('.bubble-menu, .tippy-content, .nc-textarea-rich-editor')) { |
|
|
|
|
|
|
|
isFocused.value = false |
|
|
|
|
|
|
|
emits('blur') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
true, |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
useEventListener( |
|
|
|
|
|
|
|
richTextLinkOptionRef, |
|
|
|
|
|
|
|
'focusout', |
|
|
|
|
|
|
|
(e: FocusEvent) => { |
|
|
|
|
|
|
|
const targetEl = e?.relatedTarget as HTMLElement |
|
|
|
|
|
|
|
if (!targetEl && (e.target as HTMLElement)?.closest('.bubble-menu, .tippy-content, .nc-textarea-rich-editor')) return |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!targetEl?.closest('.bubble-menu, .tippy-content, .nc-textarea-rich-editor')) { |
|
|
|
isFocused.value = false |
|
|
|
isFocused.value = false |
|
|
|
emits('blur') |
|
|
|
emits('blur') |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
true, |
|
|
|
true, |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
onClickOutside(editorDom, (e) => { |
|
|
|
|
|
|
|
if (!isFocused.value) return |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const targetEl = e?.target as HTMLElement |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!targetEl?.closest('.bubble-menu,.tippy-content, .nc-textarea-rich-editor')) { |
|
|
|
|
|
|
|
isFocused.value = false |
|
|
|
|
|
|
|
emits('blur') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
<template> |
|
|
@ -281,7 +311,15 @@ useEventListener( |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<CellRichTextSelectedBubbleMenuPopup v-if="editor && !isFormField && !isForm" :editor="editor" /> |
|
|
|
<CellRichTextSelectedBubbleMenuPopup v-if="editor && !isFormField && !isForm" :editor="editor" /> |
|
|
|
|
|
|
|
|
|
|
|
<CellRichTextLinkOptions v-if="editor" :editor="editor" /> |
|
|
|
<template v-if="shouldShowLinkOption"> |
|
|
|
|
|
|
|
<CellRichTextLinkOptions |
|
|
|
|
|
|
|
v-if="editor" |
|
|
|
|
|
|
|
ref="richTextLinkOptionRef" |
|
|
|
|
|
|
|
:editor="editor" |
|
|
|
|
|
|
|
:is-form-field="isFormField" |
|
|
|
|
|
|
|
@blur="isFocused = false" |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<EditorContent |
|
|
|
<EditorContent |
|
|
|
ref="editorDom" |
|
|
|
ref="editorDom" |
|
|
|