@ecency/render-helper 2.3.17 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +171 -17
  3. package/dist/browser/index.d.ts +32 -0
  4. package/dist/browser/index.js +1556 -0
  5. package/dist/browser/index.js.map +1 -0
  6. package/dist/node/index.cjs +1575 -0
  7. package/dist/node/index.cjs.map +1 -0
  8. package/dist/node/index.mjs +1559 -0
  9. package/dist/node/index.mjs.map +1 -0
  10. package/package.json +49 -47
  11. package/lib/cache.d.ts +0 -3
  12. package/lib/cache.js +0 -21
  13. package/lib/cache.js.map +0 -1
  14. package/lib/catch-post-image.d.ts +0 -2
  15. package/lib/catch-post-image.js +0 -76
  16. package/lib/catch-post-image.js.map +0 -1
  17. package/lib/consts/allowed-attributes.const.d.ts +0 -2
  18. package/lib/consts/allowed-attributes.const.js +0 -71
  19. package/lib/consts/allowed-attributes.const.js.map +0 -1
  20. package/lib/consts/dom-parser.const.d.ts +0 -2
  21. package/lib/consts/dom-parser.const.js +0 -12
  22. package/lib/consts/dom-parser.const.js.map +0 -1
  23. package/lib/consts/index.d.ts +0 -5
  24. package/lib/consts/index.js +0 -22
  25. package/lib/consts/index.js.map +0 -1
  26. package/lib/consts/regexes.const.d.ts +0 -44
  27. package/lib/consts/regexes.const.js +0 -49
  28. package/lib/consts/regexes.const.js.map +0 -1
  29. package/lib/consts/section-list.const.d.ts +0 -1
  30. package/lib/consts/section-list.const.js +0 -24
  31. package/lib/consts/section-list.const.js.map +0 -1
  32. package/lib/consts/white-list.const.d.ts +0 -2
  33. package/lib/consts/white-list.const.js +0 -37
  34. package/lib/consts/white-list.const.js.map +0 -1
  35. package/lib/helper.d.ts +0 -6
  36. package/lib/helper.js +0 -72
  37. package/lib/helper.js.map +0 -1
  38. package/lib/index.d.ts +0 -8
  39. package/lib/index.js +0 -19
  40. package/lib/index.js.map +0 -1
  41. package/lib/markdown-2-html.d.ts +0 -2
  42. package/lib/markdown-2-html.js +0 -25
  43. package/lib/markdown-2-html.js.map +0 -1
  44. package/lib/methods/a.method.d.ts +0 -1
  45. package/lib/methods/a.method.js +0 -647
  46. package/lib/methods/a.method.js.map +0 -1
  47. package/lib/methods/clean-reply.method.d.ts +0 -1
  48. package/lib/methods/clean-reply.method.js +0 -37
  49. package/lib/methods/clean-reply.method.js.map +0 -1
  50. package/lib/methods/get-inner-html.method.d.ts +0 -1
  51. package/lib/methods/get-inner-html.method.js +0 -16
  52. package/lib/methods/get-inner-html.method.js.map +0 -1
  53. package/lib/methods/iframe.method.d.ts +0 -1
  54. package/lib/methods/iframe.method.js +0 -159
  55. package/lib/methods/iframe.method.js.map +0 -1
  56. package/lib/methods/img.method.d.ts +0 -4
  57. package/lib/methods/img.method.js +0 -50
  58. package/lib/methods/img.method.js.map +0 -1
  59. package/lib/methods/index.d.ts +0 -7
  60. package/lib/methods/index.js +0 -24
  61. package/lib/methods/index.js.map +0 -1
  62. package/lib/methods/linkify.method.d.ts +0 -1
  63. package/lib/methods/linkify.method.js +0 -56
  64. package/lib/methods/linkify.method.js.map +0 -1
  65. package/lib/methods/markdown-to-html.method.d.ts +0 -1
  66. package/lib/methods/markdown-to-html.method.js +0 -98
  67. package/lib/methods/markdown-to-html.method.js.map +0 -1
  68. package/lib/methods/noop.method.d.ts +0 -1
  69. package/lib/methods/noop.method.js +0 -6
  70. package/lib/methods/noop.method.js.map +0 -1
  71. package/lib/methods/p.method.d.ts +0 -1
  72. package/lib/methods/p.method.js +0 -11
  73. package/lib/methods/p.method.js.map +0 -1
  74. package/lib/methods/remove-child-nodes.method.d.ts +0 -1
  75. package/lib/methods/remove-child-nodes.method.js +0 -10
  76. package/lib/methods/remove-child-nodes.method.js.map +0 -1
  77. package/lib/methods/sanitize-html.method.d.ts +0 -1
  78. package/lib/methods/sanitize-html.method.js +0 -42
  79. package/lib/methods/sanitize-html.method.js.map +0 -1
  80. package/lib/methods/text.method.d.ts +0 -1
  81. package/lib/methods/text.method.js +0 -69
  82. package/lib/methods/text.method.js.map +0 -1
  83. package/lib/methods/traverse.method.d.ts +0 -3
  84. package/lib/methods/traverse.method.js +0 -38
  85. package/lib/methods/traverse.method.js.map +0 -1
  86. package/lib/post-body-summary.d.ts +0 -2
  87. package/lib/post-body-summary.js +0 -123
  88. package/lib/post-body-summary.js.map +0 -1
  89. package/lib/proxify-image-src.d.ts +0 -5
  90. package/lib/proxify-image-src.js +0 -86
  91. package/lib/proxify-image-src.js.map +0 -1
  92. package/lib/render-helper.js +0 -1
  93. package/lib/types/entry.interface.d.ts +0 -7
  94. package/lib/types/entry.interface.js +0 -3
  95. package/lib/types/entry.interface.js.map +0 -1
  96. package/lib/types/index.d.ts +0 -2
  97. package/lib/types/index.js +0 -19
  98. package/lib/types/index.js.map +0 -1
  99. package/lib/types/xss-white-list.interface.d.ts +0 -6
  100. package/lib/types/xss-white-list.interface.js +0 -3
  101. package/lib/types/xss-white-list.interface.js.map +0 -1
  102. package/src/cache.ts +0 -15
  103. package/src/catch-post-image.spec.ts +0 -144
  104. package/src/catch-post-image.ts +0 -78
  105. package/src/consts/allowed-attributes.const.ts +0 -69
  106. package/src/consts/dom-parser.const.ts +0 -6
  107. package/src/consts/index.ts +0 -5
  108. package/src/consts/regexes.const.ts +0 -46
  109. package/src/consts/section-list.const.ts +0 -20
  110. package/src/consts/white-list.const.ts +0 -33
  111. package/src/external-types/multihashes.d.ts +0 -3
  112. package/src/helper.spec.ts +0 -16
  113. package/src/helper.ts +0 -77
  114. package/src/index.ts +0 -18
  115. package/src/markdown-2-html.spec.ts +0 -1251
  116. package/src/markdown-2-html.ts +0 -25
  117. package/src/methods/a.method.ts +0 -791
  118. package/src/methods/clean-reply.method.ts +0 -32
  119. package/src/methods/get-inner-html.method.ts +0 -11
  120. package/src/methods/iframe.method.ts +0 -176
  121. package/src/methods/img.method.ts +0 -62
  122. package/src/methods/index.ts +0 -7
  123. package/src/methods/linkify.method.ts +0 -61
  124. package/src/methods/markdown-to-html.method.ts +0 -104
  125. package/src/methods/noop.method.ts +0 -1
  126. package/src/methods/p.method.ts +0 -6
  127. package/src/methods/remove-child-nodes.method.ts +0 -5
  128. package/src/methods/sanitize-html.method.ts +0 -32
  129. package/src/methods/text.method.ts +0 -77
  130. package/src/methods/traverse.method.ts +0 -33
  131. package/src/post-body-summary.spec.ts +0 -150
  132. package/src/post-body-summary.ts +0 -130
  133. package/src/proxify-image-src.spec.ts +0 -76
  134. package/src/proxify-image-src.ts +0 -77
  135. package/src/sanitize-html.spec.ts +0 -15
  136. package/src/test/data/index.ts +0 -12
  137. package/src/test/data/json/muratkbesiroglu____sci-fi-novel-underground-city-part-13.json +0 -2120
  138. package/src/test/data/json/steemitboard____steemitboard-notify-dunsky-20181210t153450000z.json +0 -47
  139. package/src/test/data/legacy/10.json +0 -5
  140. package/src/test/data/legacy/20.json +0 -5
  141. package/src/test/data/legacy/21.json +0 -5
  142. package/src/test/data/legacy/2112524.json +0 -5
  143. package/src/test/data/legacy/22.json +0 -5
  144. package/src/test/data/legacy/23.json +0 -5
  145. package/src/test/data/legacy/24.json +0 -5
  146. package/src/test/data/legacy/25.json +0 -5
  147. package/src/test/data/legacy/26.json +0 -5
  148. package/src/test/data/legacy/27.JSON +0 -5
  149. package/src/test/data/legacy/28.json +0 -5
  150. package/src/test/data/legacy/29.json +0 -5
  151. package/src/test/data/legacy/31.json +0 -5
  152. package/src/test/snaps.json +0 -8
  153. package/src/types/entry.interface.ts +0 -7
  154. package/src/types/index.ts +0 -2
  155. package/src/types/xss-white-list.interface.ts +0 -7
@@ -1,791 +0,0 @@
1
- import {
2
- BITCHUTE_REGEX,
3
- CUSTOM_COMMUNITY_REGEX,
4
- INTERNAL_POST_REGEX,
5
- INTERNAL_POST_TAG_REGEX,
6
- D_TUBE_REGEX,
7
- D_TUBE_REGEX2,
8
- IMG_REGEX,
9
- IPFS_REGEX,
10
- MENTION_REGEX,
11
- INTERNAL_MENTION_REGEX,
12
- TOPIC_REGEX,
13
- INTERNAL_TOPIC_REGEX,
14
- POST_REGEX,
15
- CCC_REGEX,
16
- SPEAK_REGEX,
17
- TWITCH_REGEX,
18
- TWITTER_REGEX,
19
- VIMEO_REGEX,
20
- WHITE_LIST,
21
- YOUTUBE_REGEX,
22
- SPOTIFY_REGEX,
23
- RUMBLE_REGEX,
24
- BRIGHTEON_REGEX,
25
- DOMParser,
26
- LOOM_REGEX,
27
- SECTION_REGEX,
28
- SECTION_LIST
29
- } from '../consts'
30
- import { getSerializedInnerHTML } from './get-inner-html.method'
31
- import { proxifyImageSrc } from '../proxify-image-src'
32
- import { removeChildNodes } from './remove-child-nodes.method'
33
- import { extractYtStartTime, isValidPermlink, isValidUsername, sanitizePermlink } from '../helper'
34
- import { createImageHTML } from "./img.method";
35
-
36
- const normalizeValue = (value?: string | null): string => (value ? value.trim() : '')
37
-
38
- const matchesHref = (href: string, value?: string | null): boolean => {
39
- const normalizedHref = normalizeValue(href)
40
- if (!normalizedHref) {
41
- return false
42
- }
43
-
44
- return normalizeValue(value) === normalizedHref
45
- }
46
-
47
- const getInlineMeta = (el: HTMLElement, href: string) => {
48
- const textMatches = matchesHref(href, el.textContent)
49
- const titleMatches = matchesHref(href, el.getAttribute('title'))
50
-
51
- return {
52
- textMatches,
53
- nonInline: textMatches || titleMatches
54
- }
55
- }
56
-
57
-
58
- export function a(el: HTMLElement | null, forApp: boolean, webp: boolean): void {
59
- if (!el || !el.parentNode) {
60
- return
61
- }
62
- let href = el.getAttribute('href')
63
-
64
- // Continue if href has no value
65
- if (!href) {
66
- return
67
- }
68
-
69
- const className = el.getAttribute('class')
70
-
71
- // Don't touch user and hashtag links
72
- if (['markdown-author-link', 'markdown-tag-link'].indexOf(className) !== -1) {
73
- return
74
- }
75
-
76
- // Do not allow js hrefs
77
- if (href.startsWith('javascript')) {
78
- el.removeAttribute('href')
79
- return
80
- }
81
-
82
- // if href is an image url and innerHTML same with href then mark it as image
83
- // & => & can break equality
84
- if (
85
- href.match(IMG_REGEX) &&
86
- href.trim().replace(/&/g, '&') ===
87
- getSerializedInnerHTML(el).trim().replace(/&/g, '&')
88
- ) {
89
- const isLCP = false; // LCP handled elsewhere
90
- const imgHTML = createImageHTML(href, isLCP, webp);
91
- const replaceNode = DOMParser.parseFromString(imgHTML);
92
-
93
- el.parentNode.replaceChild(replaceNode, el)
94
-
95
- return
96
- }
97
-
98
- if (
99
- href.match(IPFS_REGEX) &&
100
- href.trim().replace(/&/g, '&') ===
101
- getSerializedInnerHTML(el).trim().replace(/&/g, '&') &&
102
- href.indexOf('#') === -1
103
- ) {
104
- if (forApp) {
105
- el.setAttribute('data-href', href)
106
- el.removeAttribute('href')
107
- }
108
-
109
- el.setAttribute('class', 'markdown-img-link')
110
-
111
- removeChildNodes(el)
112
-
113
- const img = el.ownerDocument.createElement('img')
114
- img.setAttribute('src', href)
115
- el.appendChild(img)
116
-
117
- return
118
- }
119
-
120
- // If a hive post
121
- const postMatch = href.match(POST_REGEX)
122
- if (postMatch && WHITE_LIST.includes(postMatch[1].replace(/www./,''))) {
123
- el.setAttribute('class', 'markdown-post-link')
124
-
125
- const tag = postMatch[2]
126
- const author = postMatch[3].replace('@', '')
127
- const permlink = sanitizePermlink(postMatch[4])
128
-
129
- if (!isValidPermlink(permlink)) return;
130
-
131
- const inlineMeta = getInlineMeta(el, href)
132
- if (inlineMeta.textMatches) {
133
- el.textContent = `@${author}/${permlink}`
134
- }
135
- const isInline = !inlineMeta.nonInline
136
- if (forApp) {
137
- el.removeAttribute('href')
138
-
139
- el.setAttribute('data-href', href)
140
- el.setAttribute('data-is-inline', '' + isInline)
141
- el.setAttribute('data-tag', tag)
142
- el.setAttribute('data-author', author)
143
- el.setAttribute('data-permlink', permlink)
144
-
145
- } else {
146
- const h = `/${tag}/@${author}/${permlink}`
147
- el.setAttribute('href', h)
148
- el.setAttribute('data-is-inline', '' + isInline)
149
- }
150
- return
151
- }
152
-
153
- // If a hive user with url
154
- const mentionMatch = href.match(MENTION_REGEX)
155
- if (mentionMatch && WHITE_LIST.includes(mentionMatch[1].replace(/www./,'')) && mentionMatch.length === 3) {
156
- const _author = mentionMatch[2].replace('@', '')
157
- if (!isValidUsername(_author)) return
158
- const author = _author.toLowerCase()
159
-
160
- el.setAttribute('class', 'markdown-author-link')
161
-
162
- if (author.indexOf('/')===-1) {
163
- if (el.textContent === href) {
164
- el.textContent = `@${author}`
165
- }
166
- if (forApp) {
167
- el.removeAttribute('href')
168
-
169
- el.setAttribute('data-author', author)
170
- } else {
171
- const h = `/@${author}`
172
- el.setAttribute('href', h)
173
- }
174
- }
175
- return
176
- }
177
-
178
- // If a tagged post and profile section links
179
- const tpostMatch = href.match(INTERNAL_POST_TAG_REGEX)
180
- if (
181
- (tpostMatch && tpostMatch.length === 4 && WHITE_LIST.some(v => tpostMatch[1].includes(v))) || (tpostMatch && tpostMatch.length === 4 && tpostMatch[1].indexOf('/') == 0)
182
- ) {
183
- // check if permlink is section or section with params ?q=xyz
184
- if (SECTION_LIST.some(v => tpostMatch[3].includes(v))) {
185
- el.setAttribute('class', 'markdown-profile-link')
186
- const author = tpostMatch[2].replace('@', '').toLowerCase()
187
- const section = tpostMatch[3]
188
-
189
- if (!isValidPermlink(section)) return;
190
- if (el.textContent === href) {
191
- el.textContent = `@${author}/${section}`
192
- }
193
- if (forApp) {
194
- const ha = `https://ecency.com/@${author}/${section}`
195
- el.setAttribute('href', ha)
196
- } else {
197
- const h = `/@${author}/${section}`
198
- el.setAttribute('href', h)
199
- }
200
- return
201
- } else {
202
- // check if domain is not whitelist and does contain dot (not tag e.g. `/ecency`)
203
- if (tpostMatch[1] && tpostMatch[1].includes('.') && !WHITE_LIST.some(v => tpostMatch[1].includes(v))) {
204
- return
205
- }
206
- let tag = 'post'
207
- // check if tag does exist and doesn't include dot likely word/tag
208
- if (tpostMatch[1] && !tpostMatch[1].includes('.')) {
209
- [, tag] = tpostMatch
210
- tag = tag.replace('/', '')
211
- }
212
-
213
- el.setAttribute('class', 'markdown-post-link')
214
- const author = tpostMatch[2].replace('@', '')
215
- const permlink = sanitizePermlink(tpostMatch[3])
216
-
217
- if (!isValidPermlink(permlink)) return;
218
-
219
- const inlineMeta = getInlineMeta(el, href)
220
- if (inlineMeta.textMatches) {
221
- el.textContent = `@${author}/${permlink}`
222
- }
223
- const isInline = !inlineMeta.nonInline
224
- if (forApp) {
225
- el.removeAttribute('href')
226
-
227
- el.setAttribute('data-href', href)
228
- el.setAttribute('data-is-inline', '' + isInline)
229
- el.setAttribute('data-tag', tag)
230
- el.setAttribute('data-author', author)
231
- el.setAttribute('data-permlink', permlink)
232
-
233
- } else {
234
- const h = `/${tag}/@${author}/${permlink}`
235
- el.setAttribute('href', h)
236
- el.setAttribute('data-is-inline', '' + isInline)
237
- }
238
-
239
- return
240
- }
241
- }
242
-
243
- // If a hive user with internal url
244
- const imentionMatch = href.match(INTERNAL_MENTION_REGEX)
245
- if (imentionMatch) {
246
- const _author = imentionMatch[0].replace('/@', '')
247
- if (!isValidUsername(_author)) return
248
- const author = _author.toLowerCase()
249
-
250
- el.setAttribute('class', 'markdown-author-link')
251
- if (author.indexOf('/')===-1) {
252
- if (el.textContent === href) {
253
- el.textContent = `@${author}`
254
- }
255
- if (forApp) {
256
- el.removeAttribute('href')
257
-
258
- el.setAttribute('data-author', author)
259
- } else {
260
- const h = `/@${author}`
261
- el.setAttribute('href', h)
262
- }
263
- }
264
- return
265
- }
266
-
267
- // If a copied post and profile section links
268
- const cpostMatch = href.match(INTERNAL_POST_REGEX)
269
- if (
270
- (cpostMatch && cpostMatch.length === 3 && cpostMatch[1].indexOf('@') === 0)
271
- ) {
272
- if (SECTION_LIST.some(v => cpostMatch[2].includes(v))) {
273
- el.setAttribute('class', 'markdown-profile-link')
274
- const author = cpostMatch[1].replace('@', '').toLowerCase()
275
- const section = cpostMatch[2]
276
-
277
- if (el.textContent === href) {
278
- el.textContent = `@${author}/${section}`
279
- }
280
- if (forApp) {
281
- const ha = `https://ecency.com/@${author}/${section}`
282
- el.setAttribute('href', ha)
283
- } else {
284
- const h = `/@${author}/${section}`
285
- el.setAttribute('href', h)
286
- }
287
- return
288
- } else {
289
- el.setAttribute('class', 'markdown-post-link')
290
-
291
- const tag = 'post'
292
-
293
- const author = cpostMatch[1].replace('@', '')
294
- const permlink = sanitizePermlink(cpostMatch[2])
295
-
296
- if (!isValidPermlink(permlink)) return;
297
-
298
- const inlineMeta = getInlineMeta(el, href)
299
-
300
- if (inlineMeta.textMatches) {
301
- el.textContent = `@${author}/${permlink}`
302
- }
303
- const isInline = !inlineMeta.nonInline
304
- if (forApp) {
305
- el.removeAttribute('href')
306
-
307
- el.setAttribute('data-href', href)
308
- el.setAttribute('data-is-inline', '' + isInline)
309
- el.setAttribute('data-tag', tag)
310
- el.setAttribute('data-author', author)
311
- el.setAttribute('data-permlink', permlink)
312
- } else {
313
- const h = `/${tag}/@${author}/${permlink}`
314
- el.setAttribute('href', h)
315
- el.setAttribute('data-is-inline', '' + isInline)
316
- }
317
-
318
- return
319
- }
320
- }
321
-
322
- // If topic with filters url
323
- const topicMatch = href.match(TOPIC_REGEX)
324
- if (topicMatch && WHITE_LIST.includes(topicMatch[1].replace(/www./,'')) && topicMatch.length === 4) {
325
- el.setAttribute('class', 'markdown-tag-link')
326
- const filter = topicMatch[2]
327
- const tag = topicMatch[3]
328
-
329
- if (el.textContent === href) {
330
- el.textContent = `/${filter}/${tag}`
331
- }
332
- if (forApp) {
333
- el.removeAttribute('href')
334
-
335
- el.setAttribute('data-filter', filter)
336
- el.setAttribute('data-tag', tag)
337
- } else {
338
- const h = `/${filter}/${tag}`
339
- el.setAttribute('href', h)
340
- }
341
- return
342
- }
343
-
344
- // If topic with filters internal url
345
- const itopicMatch = href.match(INTERNAL_TOPIC_REGEX)
346
- if (itopicMatch && itopicMatch.length === 3) {
347
- el.setAttribute('class', 'markdown-tag-link')
348
- const filter = itopicMatch[1]
349
- const tag = itopicMatch[2]
350
-
351
- if (el.textContent === href) {
352
- el.textContent = `/${filter}/${tag}`
353
- }
354
- if (forApp) {
355
- el.removeAttribute('href')
356
-
357
- el.setAttribute('data-filter', filter)
358
- el.setAttribute('data-tag', tag)
359
- } else {
360
- const h = `/${filter}/${tag}`
361
- el.setAttribute('href', h)
362
- }
363
- return
364
- }
365
-
366
- // If a custom hive community link
367
- const comMatch = href.match(CUSTOM_COMMUNITY_REGEX)
368
- if (comMatch && WHITE_LIST.includes(comMatch[1])) {
369
- el.setAttribute('class', 'markdown-community-link')
370
-
371
- const community = comMatch[2]
372
- let filter = comMatch[3].substring(1)
373
- if (!filter) filter = 'created'
374
- if (filter === 'about' || filter === 'discord') {
375
- filter = 'created'
376
- }
377
- if (el.textContent === href) {
378
- el.textContent = `${filter}/${community}`
379
- }
380
-
381
- if (forApp) {
382
- el.removeAttribute('href')
383
-
384
- el.setAttribute('data-community', community)
385
- el.setAttribute('data-filter', filter)
386
- } else {
387
- const h = `/${filter}/${community}`
388
- el.setAttribute('href', h)
389
- }
390
- return
391
- }
392
-
393
- // If a collections post
394
- const cccMatch = href.match(CCC_REGEX)
395
- if (cccMatch && WHITE_LIST.includes(cccMatch[1])) {
396
- el.setAttribute('class', 'markdown-post-link')
397
-
398
- const tag = 'ccc'
399
- const author = cccMatch[2].replace('@', '')
400
- const permlink = sanitizePermlink(cccMatch[3])
401
-
402
- if (!isValidPermlink(permlink)) return;
403
-
404
- const inlineMeta = getInlineMeta(el, href)
405
-
406
- if (inlineMeta.textMatches) {
407
- el.textContent = `@${author}/${permlink}`
408
- }
409
- const isInline = !inlineMeta.nonInline
410
- if (forApp) {
411
- el.removeAttribute('href')
412
-
413
- el.setAttribute('data-href', href)
414
- el.setAttribute('data-is-inline', '' + isInline)
415
- el.setAttribute('data-tag', tag)
416
- el.setAttribute('data-author', author)
417
- el.setAttribute('data-permlink', permlink)
418
- } else {
419
- const h = `/${tag}/@${author}/${permlink}`
420
- el.setAttribute('href', h)
421
- el.setAttribute('data-is-inline', '' + isInline)
422
- }
423
- return
424
- }
425
-
426
-
427
- const BCmatch = href.match(BITCHUTE_REGEX)
428
- if (BCmatch && el.textContent.trim() === href) {
429
- const e = BITCHUTE_REGEX.exec(href)
430
- const vid = e[1]
431
- el.setAttribute('class', 'markdown-video-link')
432
- el.removeAttribute('href')
433
-
434
- const embedSrc = `https://www.bitchute.com/embed/${vid}/`
435
-
436
- el.textContent = ''
437
-
438
- el.setAttribute('data-embed-src', embedSrc)
439
- const play = el.ownerDocument.createElement('span')
440
- play.setAttribute('class', 'markdown-video-play')
441
- el.appendChild(play)
442
- return
443
- }
444
-
445
- const RBmatch = href.match(RUMBLE_REGEX)
446
- if (RBmatch && el.textContent.trim() === href) {
447
- const e = RUMBLE_REGEX.exec(href)
448
- if (e[1]) {
449
- const vid = e[1]
450
- const embedSrc = `https://www.rumble.com/embed/${vid}/?pub=4`
451
- el.setAttribute('class', 'markdown-video-link')
452
- el.removeAttribute('href')
453
-
454
- el.textContent = ''
455
- el.setAttribute('data-embed-src', embedSrc)
456
- const play = el.ownerDocument.createElement('span')
457
- play.setAttribute('class', 'markdown-video-play')
458
- el.appendChild(play)
459
- return
460
- }
461
- }
462
-
463
- const BNmatch = href.match(BRIGHTEON_REGEX)
464
- if (BNmatch && el.textContent.trim() === href) {
465
- const e = BRIGHTEON_REGEX.exec(href)
466
- if (e[2]) {
467
- const vid = e[2]
468
- const embedSrc = `https://www.brighteon.com/embed/${vid}`
469
- el.setAttribute('class', 'markdown-video-link')
470
- el.removeAttribute('href')
471
-
472
- el.textContent = ''
473
- el.setAttribute('data-embed-src', embedSrc)
474
- const play = el.ownerDocument.createElement('span')
475
- play.setAttribute('class', 'markdown-video-play')
476
- el.appendChild(play)
477
- return
478
- }
479
- }
480
-
481
- // If a youtube video
482
- let match = href.match(YOUTUBE_REGEX)
483
- if (match && el.textContent.trim() === href) {
484
- const e = YOUTUBE_REGEX.exec(href)
485
- if (e[1]) {
486
- el.setAttribute('class', 'markdown-video-link markdown-video-link-youtube')
487
- el.removeAttribute('href')
488
-
489
- const vid = e[1]
490
- const thumbnail = proxifyImageSrc(`https://img.youtube.com/vi/${vid.split('?')[0]}/hqdefault.jpg`, 0, 0, webp ? 'webp' : 'match')
491
- const embedSrc = `https://www.youtube.com/embed/${vid}?autoplay=1`
492
-
493
- el.textContent = ''
494
-
495
- el.setAttribute('data-embed-src', embedSrc);
496
- el.setAttribute('data-youtube', vid);
497
-
498
- //extract start time if available
499
- const startTime = extractYtStartTime(href);
500
- if(startTime){
501
- el.setAttribute('data-start-time', startTime);
502
- }
503
-
504
- const thumbImg = el.ownerDocument.createElement('img')
505
- thumbImg.setAttribute('class', 'no-replace video-thumbnail')
506
- thumbImg.setAttribute('itemprop', 'thumbnailUrl')
507
- thumbImg.setAttribute('src', thumbnail)
508
-
509
- const play = el.ownerDocument.createElement('span')
510
- play.setAttribute('class', 'markdown-video-play')
511
-
512
- el.appendChild(thumbImg)
513
- el.appendChild(play)
514
-
515
- return
516
- }
517
- }
518
-
519
- // If vimeo video
520
- match = href.match(VIMEO_REGEX)
521
- if (match && href === el.textContent) {
522
- const e = VIMEO_REGEX.exec(href)
523
- if (e[3]) {
524
- el.setAttribute('class', 'markdown-video-link markdown-video-link-vimeo')
525
- el.removeAttribute('href')
526
-
527
- const embedSrc = `https://player.vimeo.com/video/${e[3]}`
528
-
529
- el.textContent = ''
530
-
531
- const ifr = el.ownerDocument.createElement('iframe')
532
- ifr.setAttribute('frameborder', '0')
533
- ifr.setAttribute('allowfullscreen', 'true')
534
- ifr.setAttribute('src', embedSrc)
535
- el.appendChild(ifr)
536
-
537
- return
538
- }
539
- }
540
-
541
- // If twitch video
542
- match = href.match(TWITCH_REGEX)
543
- if (match && href === el.textContent) {
544
- const e = TWITCH_REGEX.exec(href)
545
- if (e[2]) {
546
- el.setAttribute('class', 'markdown-video-link markdown-video-link-twitch')
547
- el.removeAttribute('href')
548
-
549
- let embedSrc = ''
550
-
551
- if (e[1] === undefined) {
552
- embedSrc = `https://player.twitch.tv/?channel=${e[2]}`
553
- } else {
554
- embedSrc = `https://player.twitch.tv/?video=${e[1]}`
555
- }
556
-
557
- el.textContent = ''
558
-
559
- const ifr = el.ownerDocument.createElement('iframe')
560
- ifr.setAttribute('frameborder', '0')
561
- ifr.setAttribute('allowfullscreen', 'true')
562
- ifr.setAttribute('src', embedSrc)
563
- el.appendChild(ifr)
564
-
565
- return
566
- }
567
- }
568
-
569
- // If a spotify audio
570
- match = href.match(SPOTIFY_REGEX)
571
- if (match && el.textContent.trim() === href) {
572
- const e = SPOTIFY_REGEX.exec(href)
573
- if (e[1]) {
574
-
575
- el.setAttribute('class', 'markdown-audio-link markdown-audio-link-spotify')
576
- el.removeAttribute('href')
577
-
578
- const embedSrc = `https://open.spotify.com/embed/playlist/${e[1]}`
579
-
580
- el.textContent = ''
581
-
582
- const ifr = el.ownerDocument.createElement('iframe')
583
- ifr.setAttribute('frameborder', '0')
584
- ifr.setAttribute('allowfullscreen', 'true')
585
- ifr.setAttribute('src', embedSrc)
586
- ifr.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-popups')
587
- el.appendChild(ifr)
588
-
589
- return
590
- }
591
- }
592
-
593
- // If a spotify audio
594
- match = href.match(LOOM_REGEX)
595
- if (match && el.textContent.trim() === href) {
596
- const e = LOOM_REGEX.exec(href)
597
- if (e[2]) {
598
-
599
- el.setAttribute('class', 'markdown-video-link markdown-video-link-loom')
600
- el.removeAttribute('href')
601
-
602
- const embedSrc = `https://www.loom.com/embed/${e[2]}`
603
-
604
- el.textContent = ''
605
-
606
- const ifr = el.ownerDocument.createElement('iframe')
607
- ifr.setAttribute('frameborder', '0')
608
- ifr.setAttribute('allowfullscreen', 'true')
609
- ifr.setAttribute('src', embedSrc)
610
- ifr.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-popups')
611
- el.appendChild(ifr)
612
-
613
- return
614
- }
615
- }
616
-
617
- // If a d.tube video
618
- match = href.match(D_TUBE_REGEX)
619
- if (match) {
620
-
621
- // Only d.tube links contains an image
622
- const imgEls = el.getElementsByTagName('img')
623
-
624
- if (imgEls.length === 1 || el.textContent.trim() === href) {
625
- const e = D_TUBE_REGEX.exec(href)
626
- // e[2] = username, e[3] object id
627
- if (e[2] && e[3]) {
628
- el.setAttribute('class', 'markdown-video-link markdown-video-link-dtube')
629
- el.removeAttribute('href')
630
-
631
-
632
- const videoHref = `https://emb.d.tube/#!/${e[2]}/${e[3]}`
633
-
634
- // el.setAttribute('data-video-href', videoHref)
635
- el.setAttribute('data-embed-src', videoHref)
636
-
637
- //process thumb img element
638
- if (imgEls.length === 1) {
639
- const thumbnail = proxifyImageSrc(imgEls[0].getAttribute('src').replace(/\s+/g, ''), 0, 0, webp ? 'webp' : 'match')
640
- const thumbImg = el.ownerDocument.createElement('img')
641
-
642
- thumbImg.setAttribute('class', 'no-replace video-thumbnail')
643
- thumbImg.setAttribute('itemprop', 'thumbnailUrl')
644
-
645
- thumbImg.setAttribute('src', thumbnail)
646
- el.appendChild(thumbImg)
647
-
648
- // Remove image.
649
- el.removeChild(imgEls[0])
650
- } else {
651
- el.textContent = '';
652
- }
653
-
654
- const play = el.ownerDocument.createElement('span')
655
- play.setAttribute('class', 'markdown-video-play')
656
-
657
-
658
- el.appendChild(play)
659
-
660
- return
661
- }
662
- }
663
- }
664
- match = href.match(D_TUBE_REGEX2)
665
- if (match) {
666
- const e = D_TUBE_REGEX2.exec(href)
667
- // e[2] = username, e[3] object id
668
- if (e[2] && e[3]) {
669
- el.setAttribute('class', 'markdown-video-link markdown-video-link-dtube')
670
- el.removeAttribute('href')
671
- el.textContent = '';
672
-
673
- const videoHref = `https://emb.d.tube/#!/${e[2]}/${e[3]}`
674
-
675
- // el.setAttribute('data-video-href', videoHref);
676
- el.setAttribute('data-embed-src', videoHref)
677
- const play = el.ownerDocument.createElement('span')
678
- play.setAttribute('class', 'markdown-video-play')
679
-
680
- el.appendChild(play)
681
-
682
-
683
- return
684
- }
685
- }
686
-
687
- // Detect 3Speak
688
- match = href.match(SPEAK_REGEX)
689
- if (match) {
690
- const imgEls = el.getElementsByTagName('img')
691
- if (imgEls.length === 1 || el.textContent.trim() === href) {
692
- const e = SPEAK_REGEX.exec(href)
693
- // e[1] / e[2] = tld , e[3] = embed address
694
- if ((e[1] || e[2]) && e[3]) {
695
- const videoHref = `https://3speak.tv/embed?v=${e[3]}`
696
- el.setAttribute('class', 'markdown-video-link markdown-video-link-speak')
697
- el.removeAttribute('href')
698
- el.setAttribute('data-embed-src', videoHref)
699
- if (el.textContent.trim() === href) {
700
- el.textContent = ''
701
- }
702
- if (imgEls.length === 1) {
703
- const thumbnail = proxifyImageSrc(imgEls[0].getAttribute('src').replace(/\s+/g, ''), 0, 0, webp ? 'webp' : 'match')
704
- const thumbImg = el.ownerDocument.createElement('img')
705
- thumbImg.setAttribute('class', 'no-replace video-thumbnail')
706
- thumbImg.setAttribute('itemprop', 'thumbnailUrl')
707
- thumbImg.setAttribute('src', thumbnail)
708
- el.appendChild(thumbImg)
709
- // Remove image.
710
- el.removeChild(imgEls[0])
711
- }
712
-
713
- const play = el.ownerDocument.createElement('span')
714
- play.setAttribute('class', 'markdown-video-play')
715
- el.appendChild(play)
716
- return
717
- }
718
- }
719
- }
720
-
721
- // If tweets
722
- const matchT = href.match(TWITTER_REGEX)
723
- if (matchT && el.textContent.trim() === href) {
724
- const e = TWITTER_REGEX.exec(href)
725
- if (e) {
726
- const url = e[0].replace(/(<([^>]+)>)/gi, '')
727
- const author = e[1].replace(/(<([^>]+)>)/gi, '')
728
-
729
- const twitterCode = `<blockquote class="twitter-tweet"><p>${url}</p>- <a href="${url}">${author}</a></blockquote>`
730
- const replaceNode = DOMParser.parseFromString(twitterCode)
731
- el.parentNode.replaceChild(replaceNode, el)
732
- return
733
- }
734
- }
735
-
736
- if (href.indexOf('https://hivesigner.com/sign/account-witness-vote?witness=') === 0 && forApp) {
737
- el.setAttribute('class', 'markdown-witnesses-link')
738
- el.setAttribute('data-href', href)
739
- el.removeAttribute('href')
740
- return
741
- }
742
-
743
- if (href.indexOf('hivesigner.com/sign/update-proposal-votes?proposal_ids') > 0 && forApp) {
744
- const m = decodeURI(href).match(/proposal_ids=\[(\d+)]/)
745
- if (m) {
746
- el.setAttribute('class', 'markdown-proposal-link')
747
- el.setAttribute('data-href', href)
748
- el.setAttribute('data-proposal', m[1])
749
- el.removeAttribute('href')
750
- return
751
- }
752
- }
753
-
754
- // If nothing matched element as external link so it will be opened in external window
755
- el.setAttribute('class', 'markdown-external-link')
756
-
757
- // Prepend https if no scheme provided
758
- if (!(/^((#)|(mailto:)|(\/(?!\/))|(((steem|hive|esteem|ecency|https?):)?\/\/))/.test(href))) {
759
- href = `https://${href}`
760
- }
761
-
762
- if (forApp) {
763
- el.setAttribute('data-href', href)
764
- const match = href.match(YOUTUBE_REGEX)
765
- if (match) {
766
- const e = YOUTUBE_REGEX.exec(href)
767
- if (e[1]) {
768
- const vid = e[1]
769
- el.setAttribute('data-youtube', vid);
770
-
771
- //extract start time if available
772
- const startTime = extractYtStartTime(href);
773
- if(startTime){
774
- el.setAttribute('data-start-time', startTime);
775
- }
776
- }
777
- }
778
- el.removeAttribute('href')
779
- } else {
780
- const matchS = href.match(SECTION_REGEX)
781
- if(matchS) {
782
- el.setAttribute('class', 'markdown-internal-link');
783
- } else {
784
- el.setAttribute('target', '_blank');
785
- el.setAttribute('rel', 'noopener');
786
- }
787
- }
788
- }
789
-
790
-
791
-