summaryrefslogtreecommitdiff
path: root/src/web/app/common/views/components/post-html.ts
blob: d365bdc498fb8278dbdb104b9906e93414798007 (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
declare const _URL_: string;

import Vue from 'vue';
import * as pictograph from 'pictograph';

import MkUrl from './url.vue';

const escape = text =>
	text
		.replace(/>/g, '>')
		.replace(/</g, '&lt;');

export default Vue.component('mk-post-html', {
	props: {
		ast: {
			type: Array,
			required: true
		},
		shouldBreak: {
			type: Boolean,
			default: true
		},
		i: {
			type: Object,
			default: null
		}
	},
	render(createElement) {
		const els = [].concat.apply([], (this as any).ast.map(token => {
			switch (token.type) {
				case 'text':
					const text = escape(token.content)
						.replace(/(\r\n|\n|\r)/g, '\n');

					if ((this as any).shouldBreak) {
						return text.split('\n').map(t => [createElement('span', t), createElement('br')]);
					} else {
						return createElement('span', text.replace(/\n/g, ' '));
					}

				case 'bold':
					return createElement('strong', escape(token.bold));

				case 'url':
					return createElement(MkUrl, {
						props: {
							url: escape(token.content),
							target: '_blank'
						}
					});

				case 'link':
					return createElement('a', {
						attrs: {
							class: 'link',
							href: escape(token.url),
							target: '_blank',
							title: escape(token.url)
						}
					}, escape(token.title));

				case 'mention':
					return (createElement as any)('a', {
						attrs: {
							href: `${_URL_}/${escape(token.username)}`,
							target: '_blank',
							dataIsMe: (this as any).i && (this as any).i.username == token.username
						},
						directives: [{
							name: 'user-preview',
							value: token.content
						}]
					}, token.content);

				case 'hashtag':
					return createElement('a', {
						attrs: {
							href: `${_URL_}/search?q=${escape(token.content)}`,
							target: '_blank'
						}
					}, escape(token.content));

				case 'code':
					return createElement('pre', [
						createElement('code', token.html)
					]);

				case 'inline-code':
					return createElement('code', token.html);

				case 'emoji':
					return createElement('span', pictograph.dic[token.emoji] || token.content);
			}
		}));

		return createElement('div', els);
	}
});