summaryrefslogtreecommitdiff
path: root/src/client/components
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2020-02-10 03:48:45 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2020-02-10 03:48:45 +0900
commit1a5f385eb5e5b82714c532e831a72a105e7cee5f (patch)
treea8364bd376276f076043e7d27087c1d22b6acaf6 /src/client/components
parentClean up (diff)
downloadmisskey-1a5f385eb5e5b82714c532e831a72a105e7cee5f.tar.gz
misskey-1a5f385eb5e5b82714c532e831a72a105e7cee5f.tar.bz2
misskey-1a5f385eb5e5b82714c532e831a72a105e7cee5f.zip
Improve mfm link
Diffstat (limited to 'src/client/components')
-rw-r--r--src/client/components/link.vue94
-rw-r--r--src/client/components/mfm.ts13
2 files changed, 100 insertions, 7 deletions
diff --git a/src/client/components/link.vue b/src/client/components/link.vue
new file mode 100644
index 0000000000..0775140c4e
--- /dev/null
+++ b/src/client/components/link.vue
@@ -0,0 +1,94 @@
+<template>
+<component :is="hasRoute ? 'router-link' : 'a'" class="xlcxczvw _link" :[attr]="hasRoute ? url.substr(local.length) : url" :rel="rel" :target="target"
+ @mouseover="onMouseover"
+ @mouseleave="onMouseleave"
+ :title="url"
+>
+ <slot></slot>
+ <fa :icon="faExternalLinkSquareAlt" v-if="target === '_blank'" class="icon"/>
+</component>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import { faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
+import { url as local } from '../config';
+import XUrlPreview from './url-preview-popup.vue';
+
+export default Vue.extend({
+ props: {
+ url: {
+ type: String,
+ required: true,
+ },
+ rel: {
+ type: String,
+ required: false,
+ }
+ },
+ data() {
+ const isSelf = this.url.startsWith(local);
+ const hasRoute = isSelf && (
+ (this.url.substr(local.length) === '/') ||
+ this.url.substr(local.length).startsWith('/@') ||
+ this.url.substr(local.length).startsWith('/notes/') ||
+ this.url.substr(local.length).startsWith('/tags/'));
+ return {
+ local,
+ self: isSelf,
+ hasRoute: hasRoute,
+ attr: hasRoute ? 'to' : 'href',
+ target: hasRoute ? null : '_blank',
+ showTimer: null,
+ hideTimer: null,
+ preview: null,
+ faExternalLinkSquareAlt
+ };
+ },
+ methods: {
+ showPreview() {
+ if (!document.body.contains(this.$el)) return;
+ if (this.preview) return;
+
+ this.preview = new XUrlPreview({
+ parent: this,
+ propsData: {
+ url: this.url,
+ source: this.$el
+ }
+ }).$mount();
+
+ document.body.appendChild(this.preview.$el);
+ },
+ closePreview() {
+ if (this.preview) {
+ this.preview.destroyDom();
+ this.preview = null;
+ }
+ },
+ onMouseover() {
+ clearTimeout(this.showTimer);
+ clearTimeout(this.hideTimer);
+ this.showTimer = setTimeout(this.showPreview, 500);
+ },
+ onMouseleave() {
+ clearTimeout(this.showTimer);
+ clearTimeout(this.hideTimer);
+ this.hideTimer = setTimeout(this.closePreview, 500);
+ }
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+.xlcxczvw {
+ word-break: break-all;
+
+ > .icon {
+ padding-left: 2px;
+ font-size: .9em;
+ font-weight: 400;
+ font-style: normal;
+ }
+}
+</style>
diff --git a/src/client/components/mfm.ts b/src/client/components/mfm.ts
index f316427897..719e9fe94a 100644
--- a/src/client/components/mfm.ts
+++ b/src/client/components/mfm.ts
@@ -2,6 +2,7 @@ import Vue, { VNode } from 'vue';
import { MfmForest } from '../../mfm/types';
import { parse, parsePlain } from '../../mfm/parse';
import MkUrl from './url.vue';
+import MkLink from './link.vue';
import MkMention from './mention.vue';
import { concat } from '../../prelude/array';
import MkFormula from './formula.vue';
@@ -158,14 +159,12 @@ export default Vue.component('misskey-flavored-markdown', {
}
case 'link': {
- return [createElement('a', {
- attrs: {
- class: 'link _link',
- href: token.node.props.url,
+ return [createElement(MkLink, {
+ key: Math.random(),
+ props: {
+ url: token.node.props.url,
rel: 'nofollow noopener',
- target: '_blank',
- title: token.node.props.url,
- }
+ },
}, genEl(token.children))];
}