Skip to content

Commit 936e1af

Browse files
authored
Merge pull request #8581 from nextcloud/backport/8571/stable33
[stable33] fix(links): allow to pass custom link handler into editor and use it
2 parents 0c74061 + d864eb6 commit 936e1af

14 files changed

Lines changed: 91 additions & 64 deletions

File tree

src/EditorFactory.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const createRichEditor = ({
4343
relativePath,
4444
isEmbedded = false,
4545
mentionSearch = undefined,
46+
openLink = undefined,
4647
} = {}) => {
4748
return new Editor({
4849
editorProps,
@@ -52,6 +53,7 @@ const createRichEditor = ({
5253
relativePath,
5354
isEmbedded,
5455
mentionSearch,
56+
openLink,
5557
}),
5658
FocusTrap,
5759
...extensions,

src/components/Editor.provider.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
import { openLink } from '../helpers/links.js'
76
import { logger } from '../helpers/logger.js'
87

98
export const FILE = Symbol('editor:file')
@@ -12,7 +11,6 @@ export const IS_MOBILE = Symbol('editor:is-mobile')
1211
export const EDITOR_UPLOAD = Symbol('editor:upload')
1312
export const HOOK_MENTION_SEARCH = Symbol('hook:mention-search')
1413
export const HOOK_MENTION_INSERT = Symbol('hook:mention-insert')
15-
export const OPEN_LINK_HANDLER = Symbol('editor:open-link-handler')
1614
export const HOOK_MENUBAR_LINK_CUSTOM_ACTION = Symbol('menubar:link-custom-action')
1715

1816
export const useIsMobileMixin = {
@@ -69,13 +67,3 @@ export const useMentionHook = {
6967
},
7068
},
7169
}
72-
export const useOpenLinkHandler = {
73-
inject: {
74-
$openLinkHandler: {
75-
from: OPEN_LINK_HANDLER,
76-
default: {
77-
openLink,
78-
},
79-
},
80-
},
81-
}

src/components/Editor.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ import Autofocus from '../extensions/Autofocus.js'
9191
9292
import { provideEditor } from '../composables/useEditor.ts'
9393
import { provideEditorFlags } from '../composables/useEditorFlags.ts'
94+
import { useOpenLinkHandler } from '../composables/useOpenLinkHandler.ts'
9495
import {
9596
ATTACHMENT_RESOLVER,
9697
FILE,
@@ -244,14 +245,16 @@ export default defineComponent({
244245
Collaboration.configure({ document: ydoc }),
245246
CollaborationCaret.configure({ provider: { awareness } }),
246247
]
247-
const mentionSearch = inject(HOOK_MENTION_SEARCH)
248+
const mentionSearch = inject(HOOK_MENTION_SEARCH, undefined)
249+
const { openLinkHandler } = useOpenLinkHandler()
248250
const editor = isRichEditor
249251
? createRichEditor({
250252
connection,
251253
relativePath: props.relativePath,
252254
extensions,
253255
isEmbedded: props.isEmbedded,
254256
mentionSearch,
257+
openLink: openLinkHandler.openLink,
255258
})
256259
: createPlainEditor({ language, extensions })
257260
provideEditor(editor)

src/components/Editor/MarkdownContentEditor.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { editorFlagsKey } from '../../composables/useEditorFlags.ts'
3131
import { provideEditorHeadings } from '../../composables/useEditorHeadings.ts'
3232
import { useEditorMethods } from '../../composables/useEditorMethods.ts'
3333
import { provideEditorWidth } from '../../composables/useEditorWidth.ts'
34+
import { useOpenLinkHandler } from '../../composables/useOpenLinkHandler.ts'
3435
import { FocusTrap, RichText } from '../../extensions/index.js'
3536
import { createMarkdownSerializer } from '../../extensions/Markdown.js'
3637
import AttachmentResolver from '../../services/AttachmentResolver.js'
@@ -82,9 +83,11 @@ export default {
8283
emits: ['update:content'],
8384
8485
setup(props) {
86+
const { openLinkHandler } = useOpenLinkHandler()
8587
const extensions = [
8688
RichText.configure({
8789
extensions: [UndoRedo],
90+
openLink: openLinkHandler.openLink,
8891
}),
8992
FocusTrap,
9093
]

src/components/Editor/PreviewOptions.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import ContentCopyIcon from 'vue-material-design-icons/ContentCopy.vue'
7272
import DotsVerticalIcon from 'vue-material-design-icons/DotsVertical.vue'
7373
import OpenIcon from 'vue-material-design-icons/OpenInNew.vue'
7474
import DeleteOutlineIcon from 'vue-material-design-icons/TrashCanOutline.vue'
75+
import { useOpenLinkHandler } from '../../composables/useOpenLinkHandler.ts'
7576
import CopyToClipboardMixin from '../../mixins/CopyToClipboardMixin.js'
7677
7778
export default {
@@ -104,6 +105,11 @@ export default {
104105
},
105106
},
106107
108+
setup() {
109+
const { openLinkHandler } = useOpenLinkHandler()
110+
return { openLinkHandler }
111+
},
112+
107113
data() {
108114
return {
109115
open: false,
@@ -126,7 +132,7 @@ export default {
126132
},
127133
openLink() {
128134
if (!this.href) return
129-
window.open(this.href, '_blank').focus()
135+
this.openLinkHandler.openLink(this.href)
130136
},
131137
async copyLink() {
132138
await this.copyToClipboard(this.href)

src/components/Link/LinkBubbleView.vue

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ import CloseIcon from 'vue-material-design-icons/Close.vue'
9797
import OpenInNewIcon from 'vue-material-design-icons/OpenInNew.vue'
9898
import PencilOutlineIcon from 'vue-material-design-icons/PencilOutline.vue'
9999
100-
import { useOpenLinkHandler } from '../Editor.provider.ts'
100+
import { useOpenLinkHandler } from '../../composables/useOpenLinkHandler.ts'
101101
import PreviewOptions from '../Editor/PreviewOptions.vue'
102102
103103
const PROTOCOLS_WITH_PREVIEW = ['http:', 'https:']
@@ -116,8 +116,6 @@ export default {
116116
PencilOutlineIcon,
117117
},
118118
119-
mixins: [useOpenLinkHandler],
120-
121119
props: {
122120
editor: {
123121
type: Object,
@@ -129,6 +127,11 @@ export default {
129127
},
130128
},
131129
130+
setup() {
131+
const { openLinkHandler } = useOpenLinkHandler()
132+
return { openLinkHandler }
133+
},
134+
132135
data() {
133136
return {
134137
isEditable: false,
@@ -191,7 +194,7 @@ export default {
191194
},
192195
193196
openLink(href) {
194-
this.$openLinkHandler.openLink(href)
197+
this.openLinkHandler.openLink(href)
195198
},
196199
197200
onReferenceListLoaded() {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { inject } from 'vue'
7+
import { openLink } from '../helpers/links.js'
8+
9+
export const OPEN_LINK_HANDLER = Symbol('editor:open-link-handler')
10+
11+
/**
12+
* Inject provided link handler
13+
*/
14+
export function useOpenLinkHandler() {
15+
const openLinkHandler = inject(OPEN_LINK_HANDLER, { openLink })
16+
return { openLinkHandler }
17+
}

src/editor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import {
1111
HOOK_MENTION_INSERT,
1212
HOOK_MENTION_SEARCH,
1313
HOOK_MENUBAR_LINK_CUSTOM_ACTION,
14-
OPEN_LINK_HANDLER,
1514
} from './components/Editor.provider.ts'
1615
import { ACTION_ATTACHMENT_PROMPT } from './components/Editor/MediaHandler.provider.js'
16+
import { OPEN_LINK_HANDLER } from './composables/useOpenLinkHandler.ts'
1717
import { encodeAttachmentFilename } from './helpers/attachmentFilename.ts'
1818
import { openLink } from './helpers/links.js'
1919
// eslint-disable-next-line import/no-unresolved, n/no-missing-import

src/extensions/LinkBubble.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import { Extension } from '@tiptap/core'
7-
import { hideLinkBubble, linkBubble } from '../plugins/links.js'
7+
import { hideLinkBubble, linkBubble } from '../plugins/links.ts'
88

99
const LinkBubble = Extension.create({
1010
name: 'linkViewBubble',

src/extensions/RichText.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export default Extension.create({
6161
relativePath: null,
6262
isEmbedded: false,
6363
mentionSearch: undefined,
64+
openLink: undefined,
6465
}
6566
},
6667

@@ -122,6 +123,7 @@ export default Extension.create({
122123
openOnClick: true,
123124
shouldAutoLink: (href) => /^https?:\/\//.test(href),
124125
relativePath: this.options.relativePath,
126+
openLink: this.options.openLink,
125127
}),
126128
LinkBubble,
127129
this.options.editing

0 commit comments

Comments
 (0)