summaryrefslogtreecommitdiff
path: root/src/client/app/common/views/components/post-html.vue
blob: 1c949052b9804029bc90a206e66c3c04fd64205c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<template><div class="mk-post-html" v-html="html"></div></template>

<script lang="ts">
import Vue from 'vue';
import getAcct from '../../../../../common/user/get-acct';
import { url } from '../../../config';

function markUrl(a) {
	while (a.firstChild) {
		a.removeChild(a.firstChild);
	}

	const schema = document.createElement('span');
	const delimiter = document.createTextNode('//');
	const host = document.createElement('span');
	const pathname = document.createElement('span');
	const query = document.createElement('span');
	const hash = document.createElement('span');

	schema.className = 'schema';
	schema.textContent = a.protocol;

	host.className = 'host';
	host.textContent = a.host;

	pathname.className = 'pathname';
	pathname.textContent = a.pathname;

	query.className = 'query';
	query.textContent = a.search;

	hash.className = 'hash';
	hash.textContent = a.hash;

	a.appendChild(schema);
	a.appendChild(delimiter);
	a.appendChild(host);
	a.appendChild(pathname);
	a.appendChild(query);
	a.appendChild(hash);
}

function markMe(me, a) {
	a.setAttribute("data-is-me", me && `${url}/@${getAcct(me)}` == a.href);
}

function markTarget(a) {
	a.setAttribute("target", "_blank");
}

export default Vue.component('mk-post-html', {
	props: {
		html: {
			type: String,
			required: true
		},
		i: {
			type: Object,
			default: null
		}
	},
	watch {
		html: {
			handler() {
				this.$nextTick(() => [].forEach.call(this.$el.getElementsByTagName('a'), a => {
					if (a.href === a.textContent) {
						markUrl(a);
					} else {
						markMe((this as any).i, a);
					}

					markTarget(a);
				}));
			},
			immediate: true,
		}
	}
});
</script>

<style lang="stylus">
.mk-post-html
	a
		word-break break-all

		> .schema
			opacity 0.5

		> .host
			font-weight bold

		> .pathname
			opacity 0.8

		> .query
			opacity 0.5

		> .hash
			font-style italic

	p
		margin 0
</style>