git ssb

7+

dinoworm ๐Ÿ› / patchcore



Tree: eb7933358238526bccf4c320ca689b9269c61f95

Files: eb7933358238526bccf4c320ca689b9269c61f95 / message / html / markdown.js

2918 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 // handle patchwork style mentions and custom emoji.
23 var mentions = {}
24 var typeLookup = {}
25 var emojiMentions = {}
26 if (Array.isArray(content.mentions)) {
27 content.mentions.forEach(function (link) {
28 if (link && link.link && link.type) {
29 typeLookup[link.link] = link.type
30 }
31 if (link && link.name && link.link) {
32 if (link.emoji) emojiMentions[link.name] = link.link
33 else mentions['@' + link.name] = link.link
34 }
35 })
36 }
37
38 return h('Markdown', {
39 hooks: [
40 LoadingBlobHook(api.blob.obs.has)
41 ],
42 innerHTML: renderer.block(content.text, {
43 emoji: (emoji) => {
44 var url = emojiMentions[emoji]
45 ? api.blob.sync.url(emojiMentions[emoji])
46 : api.emoji.sync.url(emoji)
47 return renderEmoji(emoji, url)
48 },
49 toUrl: (id) => {
50 if (ref.isBlob(id)) {
51 var blob = ref.parseBlob(id)
52 var url = api.blob.sync.url(blob.link)
53 var query = {}
54 if (blob.query && blob.query.unbox) query['unbox'] = blob.query.unbox
55 if (typeLookup[blob.link]) query['contentType'] = typeLookup[blob.link]
56 return url + '?' + querystring.stringify(query)
57 }
58 if (mentions[id]) {
59 return mentions[id]
60 } else if (ref.isLink(id) || id.startsWith('#') || id.startsWith('?')) {
61 return id
62 }
63 return false
64 },
65 imageLink: (id) => id
66 })
67 })
68 }
69
70 function renderEmoji (emoji, url) {
71 if (!url) return ':' + emoji + ':'
72 return `
73 <img
74 src="${htmlEscape(url)}"
75 alt=":${htmlEscape(emoji)}:"
76 title=":${htmlEscape(emoji)}:"
77 class="emoji"
78 >
79 `
80 }
81}
82
83function LoadingBlobHook (hasBlob) {
84 return function (element) {
85 var releases = []
86 element.querySelectorAll('img').forEach(img => {
87 var id = ref.extract(img.src)
88 if (id) {
89 releases.push(watch(hasBlob(id), has => {
90 if (has === false) {
91 img.classList.add('-pending')
92 } else {
93 img.classList.remove('-pending')
94 }
95 }))
96 }
97 })
98 return function () {
99 while (releases.length) {
100 releases.pop()()
101 }
102 }
103 }
104}
105

Built with git-ssb-web