diff --git a/src/components/NcRichText/NcRichText.vue b/src/components/NcRichText/NcRichText.vue
index c8e3920119..ec3aea99d8 100644
--- a/src/components/NcRichText/NcRichText.vue
+++ b/src/components/NcRichText/NcRichText.vue
@@ -320,6 +320,7 @@ import { RouterLink } from 'vue-router'
import NcCheckboxRadioSwitch from '../NcCheckboxRadioSwitch/NcCheckboxRadioSwitch.vue'
import NcReferenceList from './NcReferenceList.vue'
import NcRichTextCopyButton from './NcRichTextCopyButton.vue'
+import NcRichTextExternalLink from './NcRichTextExternalLink.vue'
import { createElementId } from '../../utils/createElementId.ts'
import { getRoute, parseUrl, remarkAutolink } from './autolink.ts'
import { remarkPlaceholder } from './remarkPlaceholder.ts'
@@ -532,11 +533,9 @@ export default {
return entry
}
const { component, props } = entry
- // do not override class of NcLink
- const componentClass = component.name === 'NcLink' ? undefined : 'rich-text--component'
return h(component, {
...props,
- class: componentClass,
+ class: 'rich-text--component',
})
})
}
@@ -632,6 +631,7 @@ export default {
if (String(type) === 'a') {
const route = getRoute(this.$router, props.href)
if (route) {
+ // Resolved link to this app; render RouterLink
delete props.href
delete props.target
@@ -640,6 +640,18 @@ export default {
to: route,
}, { default: () => children })
}
+
+ const isAbsoluteURL = /^https?:\/\//.test(props.href)
+ if (isAbsoluteURL) {
+ // External link; render normally, open in the new tab
+ props.href = props.href.trim()
+ return h(NcRichTextExternalLink, props, children)
+ } else {
+ // Unresolved relative link that does not belong to this app; render only children
+ delete props.href
+ delete props.target
+ return h('span', props, children)
+ }
}
return h(type, props, children)
}
@@ -684,13 +696,6 @@ export default {
.rich-text--fallback, .rich-text-component {
display: inline;
}
-
- .rich-text--external-link {
- text-decoration: underline;
- &:after {
- content: ' ↗';
- }
- }
}
/* Markdown styles */
diff --git a/src/components/NcRichText/NcRichTextExternalLink.vue b/src/components/NcRichText/NcRichTextExternalLink.vue
new file mode 100644
index 0000000000..ae48831b4a
--- /dev/null
+++ b/src/components/NcRichText/NcRichTextExternalLink.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+ {{ href }}
+
+
+
+
+
+
+
+An internal component
+
diff --git a/src/components/NcRichText/autolink.ts b/src/components/NcRichText/autolink.ts
index 0af3b0a6da..e253f8cbbe 100644
--- a/src/components/NcRichText/autolink.ts
+++ b/src/components/NcRichText/autolink.ts
@@ -9,28 +9,10 @@ import type { Router } from 'vue-router'
import { getBaseUrl, getRootUrl } from '@nextcloud/router'
import { u } from 'unist-builder'
import { SKIP, visitParents } from 'unist-util-visit-parents'
-import { defineComponent, h } from 'vue'
+import NcRichTextExternalLink from './NcRichTextExternalLink.vue'
import { logger } from '../../utils/logger.ts'
import { URL_PATTERN_AUTOLINK } from './helpers.js'
-const NcLink = defineComponent({
- name: 'NcLink',
- props: {
- href: {
- type: String,
- required: true,
- },
- },
- render() {
- return h('a', {
- href: this.href,
- rel: 'noopener noreferrer',
- target: '_blank',
- class: 'rich-text--external-link',
- }, [this.href.trim()])
- },
-})
-
/**
*
* @param root0
@@ -99,7 +81,7 @@ export function parseUrl(text: string) {
textAfter = lastChar
}
list.push(textBefore)
- list.push({ component: NcLink, props: { href } })
+ list.push({ component: NcRichTextExternalLink, props: { href: href.trim(), decorateExternal: true } })
if (textAfter) {
list.push(textAfter)
}