git ssb

7+

dinoworm ๐Ÿ› / patchcore



Tree: 781e1c19862d0d3327dd9a68e0c497d9f876cc0f

Files: 781e1c19862d0d3327dd9a68e0c497d9f876cc0f / message / html / markdown.js

3070 bytesRaw
1const renderer = require('ssb-markdown')
2const h = require('mutant/h')
3const ref = require('ssb-ref')
4const nest = require('depnest')
5var htmlEscape = require('html-escape')
6var watch = require('mutant/watch')
7const querystring = require('querystring');
8
9exports.needs = nest({
10 'blob.sync.url': 'first',
11 'blob.obs.has': 'first',
12 'emoji.sync.url': 'first'
13})
14
15exports.gives = nest('message.html.markdown')
16
17exports.create = function (api) {
18 return nest('message.html.markdown', markdown)
19
20 function markdown (content) {
21 if (typeof content === 'string') { content = {text: content} }
22 var mentions = {}
23 var typeLookup = {}
24 var emojiMentions = {}
25 if (Array.isArray(content.mentions)) {
26 content.mentions.forEach(function (link) {
27 if (link && link.link && link.type) {
28 typeLookup[link.link] = link.type
29 }
30 if (link && link.name && link.link) {
31 if (link.emoji) {
32 // handle custom emoji
33 emojiMentions[link.name] = link.link
34 } else {
35 // handle old-style patchwork v2 mentions (deprecated)
36 mentions['@' + link.name] = link.link
37 }
38 }
39 })
40 }
41
42 return h('Markdown', {
43 hooks: [
44 LoadingBlobHook(api.blob.obs.has)
45 ],
46 innerHTML: renderer.block(content.text, {
47 emoji: (emoji) => {
48 var url = emojiMentions[emoji]
49 ? api.blob.sync.url(emojiMentions[emoji])
50 : api.emoji.sync.url(emoji)
51 return renderEmoji(emoji, url)
52 },
53 toUrl: (id) => {
54 var link = ref.parseLink(id)
55 if (link && ref.isBlob(link.link)) {
56 var url = api.blob.sync.url(link.link)
57 var query = {}
58 if (link.query && link.query.unbox) query['unbox'] = link.query.unbox
59 if (typeLookup[link.link]) query['contentType'] = typeLookup[link.link]
60 return url + '?' + querystring.stringify(query)
61 } else if (link || id.startsWith('#') || id.startsWith('?')) {
62 return id
63 } else if (mentions[id]) {
64 // handle old-style patchwork v2 mentions (deprecated)
65 return mentions[id]
66 }
67 return false
68 },
69 imageLink: (id) => id
70 })
71 })
72 }
73
74 function renderEmoji (emoji, url) {
75 if (!url) return ':' + emoji + ':'
76 return `
77 <img
78 src="${htmlEscape(url)}"
79 alt=":${htmlEscape(emoji)}:"
80 title=":${htmlEscape(emoji)}:"
81 class="emoji"
82 >
83 `
84 }
85}
86
87function LoadingBlobHook (hasBlob) {
88 return function (element) {
89 var releases = []
90 element.querySelectorAll('img').forEach(img => {
91 var id = ref.extract(img.src)
92 if (id) {
93 releases.push(watch(hasBlob(id), has => {
94 if (has === false) {
95 img.classList.add('-pending')
96 } else {
97 img.classList.remove('-pending')
98 }
99 }))
100 }
101 })
102 return function () {
103 while (releases.length) {
104 releases.pop()()
105 }
106 }
107 }
108}
109

Built with git-ssb-web