diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2020-02-10 03:48:45 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2020-02-10 03:48:45 +0900 |
| commit | 1a5f385eb5e5b82714c532e831a72a105e7cee5f (patch) | |
| tree | a8364bd376276f076043e7d27087c1d22b6acaf6 /src/client/components | |
| parent | Clean up (diff) | |
| download | misskey-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.vue | 94 | ||||
| -rw-r--r-- | src/client/components/mfm.ts | 13 |
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))]; } |