git ssb

30+

cel / git-ssb-web



Tree: 4e2e329990a36a7d36ef11a1381f321f1b63459a

Files: 4e2e329990a36a7d36ef11a1381f321f1b63459a / lib / util.js

4311 bytesRaw
1var pull = require('pull-stream')
2var catMap = require('pull-cat-map')
3var Highlight = require('highlight.js')
4var u = exports
5
6u.imgMimes = {
7 png: 'image/png',
8 jpeg: 'image/jpeg',
9 jpg: 'image/jpeg',
10 gif: 'image/gif',
11 tif: 'image/tiff',
12 svg: 'image/svg+xml',
13 bmp: 'image/bmp'
14}
15
16u.getExtension = function(filename) {
17 return (/\.([^.]+)$/.exec(filename) || [,filename])[1]
18}
19
20u.readNext = function (fn) {
21 var next
22 return function (end, cb) {
23 if (next) return next(end, cb)
24 fn(function (err, _next) {
25 if (err) return cb(err)
26 next = _next
27 next(null, cb)
28 })
29 }
30}
31
32u.readOnce = function (fn) {
33 var ended
34 return function (end, cb) {
35 fn(function (err, data) {
36 if (err || ended) return cb(err || ended)
37 ended = true
38 cb(null, data)
39 })
40 }
41}
42
43u.sourceMap = function sourceMap (source, fn) {
44 return pull(
45 source,
46 pull.filter(Boolean),
47 catMap(fn)
48 )
49}
50
51u.escape = function (str) {
52 return String(str)
53 .replace(/&/g, '&')
54 .replace(/</g, '&lt;')
55 .replace(/>/g, '&gt;')
56 .replace(/"/g, '&quot;')
57}
58
59u.encodeLink = function (url) {
60 if (!Array.isArray(url)) url = [url]
61 return '/' + url.map(encodeURIComponent).join('/')
62}
63
64u.link = function (parts, text, raw, props) {
65 if (text == null) text = parts[parts.length-1]
66 if (!raw) text = u.escape(text)
67 return '<a href="' + u.encodeLink(parts) + '"' +
68 (props ? ' ' + props : '') +
69 '>' + text + '</a>'
70}
71
72u.timestamp = function (time, req) {
73 time = Number(time)
74 var d = new Date(time)
75 return '<span title="' + time + '">' +
76 d.toLocaleString(req._locale) + '</span>'
77}
78
79u.nav = function (links, page, after) {
80 return ['<nav>'].concat(
81 links.map(function (link) {
82 var href = typeof link[0] == 'string' ? link[0] : u.encodeLink(link[0])
83 var props = link[2] == page ? ' class="active"' : ''
84 return '<a href="' + href + '"' + props + '>' + link[1] + '</a>'
85 }), after || '', '</nav>').join('')
86}
87
88u.hiddenInputs = function (values) {
89 return Object.keys(values).map(function (key) {
90 return '<input type="hidden"' +
91 ' name="' + u.escape(key) + '"' +
92 ' value="' + u.escape(values[key]) + '"/>'
93 }).join('')
94}
95
96u.highlight = function(code, lang) {
97 if (code.length > 100000) return u.escape(code)
98 try {
99 return lang
100 ? Highlight.highlight(lang, code).value
101 : Highlight.highlightAuto(code).value
102 } catch(e) {
103 if (/^Unknown language/.test(e.message))
104 return u.escape(code)
105 throw e
106 }
107}
108
109u.pre = function (text) {
110 return '<pre>' + u.escape(text) + '</pre>'
111}
112
113u.json = function (obj) {
114 return u.linkify(u.pre(JSON.stringify(obj, null, 2)))
115}
116
117u.linkify = function (text) {
118 // regex is from ssb-ref
119 return text.replace(/(@|%|&|&amp;)[A-Za-z0-9\/+]{43}=\.[\w\d]+/g, function (str) {
120 return '<a href="/' + encodeURIComponent(str) + '">' + str + '</a>'
121 })
122}
123
124u.readObjectString = function (obj, cb) {
125 pull(obj.read, pull.collect(function (err, bufs) {
126 if (err) return cb(err)
127 cb(null, Buffer.concat(bufs, obj.length).toString('utf8'))
128 }))
129}
130
131u.pullReverse = function () {
132 return function (read) {
133 return u.readNext(function (cb) {
134 pull(read, pull.collect(function (err, items) {
135 cb(err, items && pull.values(items.reverse()))
136 }))
137 })
138 }
139}
140
141function compareMsgs(a, b) {
142 return (a.value.timestamp - b.value.timestamp) || (a.key - b.key)
143}
144
145u.pullSort = function (comparator, descending) {
146 return function (read) {
147 return u.readNext(function (cb) {
148 pull(read, pull.collect(function (err, items) {
149 if (err) return cb(err)
150 items.sort(comparator)
151 if (descending) items.reverse()
152 cb(null, pull.values(items))
153 }))
154 })
155 }
156}
157
158u.sortMsgs = function (descending) {
159 return u.pullSort(compareMsgs, descending)
160}
161
162u.truncate = function (str, len) {
163 str = String(str)
164 return str.length < len ? str : str.substr(0, len) + '…'
165}
166
167u.messageTitle = function (msg) {
168 var c = msg.value.content
169 return u.truncate(c.title || c.text || msg.key, 40)
170}
171
172u.ifModifiedSince = function (req, lastMod) {
173 var ifModSince = req.headers['if-modified-since']
174 if (!ifModSince) return false
175 var d = new Date(ifModSince)
176 return d && Math.floor(d/1000) >= Math.floor(lastMod/1000)
177}
178

Built with git-ssb-web