@ecency/render-helper 2.2.1 → 2.2.5
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.
- package/lib/consts/allowed-attributes.const.js +2 -1
- package/lib/consts/allowed-attributes.const.js.map +1 -1
- package/lib/consts/regexes.const.d.ts +1 -0
- package/lib/consts/regexes.const.js +3 -2
- package/lib/consts/regexes.const.js.map +1 -1
- package/lib/consts/white-list.const.js +3 -1
- package/lib/consts/white-list.const.js.map +1 -1
- package/lib/methods/a.method.js +37 -27
- package/lib/methods/a.method.js.map +1 -1
- package/lib/methods/clean-reply.method.js +20 -18
- package/lib/methods/clean-reply.method.js.map +1 -1
- package/lib/methods/iframe.method.js +6 -0
- package/lib/methods/iframe.method.js.map +1 -1
- package/lib/methods/linkify.method.js +13 -7
- package/lib/methods/linkify.method.js.map +1 -1
- package/lib/render-helper.js +1 -1
- package/package.json +1 -1
- package/src/consts/allowed-attributes.const.ts +2 -1
- package/src/consts/regexes.const.ts +2 -1
- package/src/consts/white-list.const.ts +3 -1
- package/src/markdown-2-html.spec.ts +66 -6
- package/src/methods/a.method.ts +35 -26
- package/src/methods/clean-reply.method.ts +20 -18
- package/src/methods/iframe.method.ts +8 -1
- package/src/methods/linkify.method.ts +12 -8
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@ export const INTERNAL_POST_TAG_REGEX = /\/(.*)\/(@[\w.\d-]+)\/(.*)/i
|
|
|
12
12
|
export const INTERNAL_POST_REGEX = /^\/(@[\w.\d-]+)\/(.*)$/i
|
|
13
13
|
export const CUSTOM_COMMUNITY_REGEX = /^https?:\/\/(.*)\/c\/(hive-\d+)(.*)/i
|
|
14
14
|
export const YOUTUBE_REGEX = /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([^& \n<]+)(?:[^ \n<]+)?/g
|
|
15
|
-
export const YOUTUBE_EMBED_REGEX = /^(https?:)?\/\/www.youtube.com\/embed\/.*/i
|
|
15
|
+
export const YOUTUBE_EMBED_REGEX = /^(https?:)?\/\/www.youtube.com\/(embed|shorts)\/.*/i
|
|
16
16
|
export const VIMEO_REGEX = /(https?:\/\/)?(www\.)?(?:vimeo)\.com.*(?:videos|video|channels|)\/([\d]+)/i
|
|
17
17
|
export const VIMEO_EMBED_REGEX = /https:\/\/player\.vimeo\.com\/video\/([0-9]+)/
|
|
18
18
|
export const BITCHUTE_REGEX = /^(?:https?:\/\/)?(?:www\.)?bitchute.com\/(?:video|embed)\/([a-z0-9]+)/i
|
|
@@ -38,3 +38,4 @@ export const TWITCH_EMBED_REGEX = /^(https?:)?\/\/player.twitch.tv\/.*/i
|
|
|
38
38
|
export const BRAND_NEW_TUBE_REGEX = /^https:\/\/brandnewtube\.com\/embed\/[a-z0-9]+$/i
|
|
39
39
|
export const LOOM_REGEX = /^(https?:)?\/\/www.loom.com\/share\/(.*)/i
|
|
40
40
|
export const LOOM_EMBED_REGEX = /^(https?:)?\/\/www.loom.com\/embed\/(.*)/i
|
|
41
|
+
export const AUREAL_EMBED_REGEX = /^(https?:\/\/)?(www\.)?(?:aureal-embed)\.web\.app\/([0-9]+)/i
|
|
@@ -428,14 +428,14 @@ describe('Markdown2Html', () => {
|
|
|
428
428
|
expect(markdown2Html(input)).toBe(expected)
|
|
429
429
|
})
|
|
430
430
|
|
|
431
|
-
it('28- Should handle peakd post links', () => {
|
|
431
|
+
it('28 - Should handle peakd post links', () => {
|
|
432
432
|
const input = {
|
|
433
433
|
author: 'foo3343',
|
|
434
434
|
permlink: 'bar3243',
|
|
435
435
|
last_update: '2019-05-10T09:15:21',
|
|
436
436
|
body: 'https://peakd.com/@demo/tests'
|
|
437
437
|
}
|
|
438
|
-
const expected = '<p><a class
|
|
438
|
+
const expected = '<p><a class=\"markdown-post-link\" data-tag=\"post\" data-author=\"demo\" data-permlink=\"tests\">@demo/tests</a></p>'
|
|
439
439
|
|
|
440
440
|
expect(markdown2Html(input)).toBe(expected)
|
|
441
441
|
})
|
|
@@ -663,7 +663,7 @@ describe('Markdown2Html', () => {
|
|
|
663
663
|
last_update: '2019-05-10T09:15:21',
|
|
664
664
|
body: '[click here](https://peakd.com/@praetoria-cartel/wallet) direct link https://peakd.com/@praetoria-cartel/posts'
|
|
665
665
|
}
|
|
666
|
-
const expected = '<p><a href
|
|
666
|
+
const expected = '<p><a href=\"https://ecency.com/@praetoria-cartel/wallet\" class=\"markdown-profile-link\">click here</a> direct link <a href=\"https://ecency.com/@praetoria-cartel/posts\" class=\"markdown-profile-link\">@praetoria-cartel/posts</a></p>'
|
|
667
667
|
|
|
668
668
|
expect(markdown2Html(input)).toBe(expected)
|
|
669
669
|
})
|
|
@@ -675,12 +675,12 @@ describe('Markdown2Html', () => {
|
|
|
675
675
|
last_update: '2019-05-10T09:15:21',
|
|
676
676
|
body: 'for history refer to this fine post /@offgridlife/proofofbrain-golden-rule-do-to-others-what-you-want-them-to-do-to-you and while you are in the community'
|
|
677
677
|
}
|
|
678
|
-
const expected = '<p><span>for history refer to this fine post <a class=\"markdown-post-link\" data-author=\"offgridlife\" data-tag=\"post\" data-permlink=\"proofofbrain-golden-rule-do-to-others-what-you-want-them-to-do-to-you\"
|
|
678
|
+
const expected = '<p><span>for history refer to this fine post <a class=\"markdown-post-link\" data-author=\"offgridlife\" data-tag=\"post\" data-permlink=\"proofofbrain-golden-rule-do-to-others-what-you-want-them-to-do-to-you\">@offgridlife/proofofbrain-golden-rule-do-to-others-what-you-want-them-to-do-to-you</a> and while you are in the community</span></p>'
|
|
679
679
|
|
|
680
680
|
expect(markdown2Html(input)).toBe(expected)
|
|
681
681
|
})
|
|
682
682
|
|
|
683
|
-
it('
|
|
683
|
+
it('48 - Should handle Bitchute links', () => {
|
|
684
684
|
const input = {
|
|
685
685
|
author: 'foo347',
|
|
686
686
|
permlink: 'bar347',
|
|
@@ -805,6 +805,66 @@ describe('Markdown2Html', () => {
|
|
|
805
805
|
const expected = '<p><strong>It\'s a Secret, But is it good to have secrets?</strong><br /><a data-tag=\"hive-123046\" data-author=\"ecotrain\" data-permlink=\"ecotrain-question-of-the-week-season-5-1tie-up-post-it-s-a-secret-but-is-it-good-to-have-secrets\" class=\"markdown-post-link\">/@ecotrain/ecotrain-question-of-the-week-season-5-1tie-up-post-it-s-a-secret-but-is-it-good-to-have-secrets</a></p>'
|
|
806
806
|
expect(markdown2Html(input)).toBe(expected)
|
|
807
807
|
})
|
|
808
|
+
|
|
809
|
+
it('59 - Should handle Aureal iframe', () => {
|
|
810
|
+
const input = {
|
|
811
|
+
author: 'foo359',
|
|
812
|
+
permlink: 'bar359',
|
|
813
|
+
last_update: '2021-10-23T09:15:21',
|
|
814
|
+
body: 'this is link <iframe loading="lazy" src="https://aureal-embed.web.app/535939" width="100%" height="200" frameborder="0" data-rocket-lazyload="fitvidscompatible" class="lazyloaded" data-ll-status="loaded"></iframe>'
|
|
815
|
+
}
|
|
816
|
+
const expected = '<p>this is link <iframe src=\"https://aureal-embed.web.app/535939\" frameborder=\"0\" class=\"lazyloaded\"></iframe></p>'
|
|
817
|
+
|
|
818
|
+
expect(markdown2Html(input)).toBe(expected)
|
|
819
|
+
})
|
|
820
|
+
|
|
821
|
+
it('60 - Should username with permlink', () => {
|
|
822
|
+
const input = {
|
|
823
|
+
author: 'foo360',
|
|
824
|
+
permlink: 'bar360',
|
|
825
|
+
last_update: '2021-10-23T09:15:21',
|
|
826
|
+
body: 'this is link @demo/test for internal'
|
|
827
|
+
}
|
|
828
|
+
const expected = '<p><span>this is link <a class=\"markdown-post-link\" data-author=\"demo\" data-tag=\"post\" data-permlink=\"test\">@demo/test</a> for internal</span></p>'
|
|
829
|
+
|
|
830
|
+
expect(markdown2Html(input)).toBe(expected)
|
|
831
|
+
})
|
|
832
|
+
|
|
833
|
+
it('61 - Should username with permlink with slash', () => {
|
|
834
|
+
const input = {
|
|
835
|
+
author: 'foo361',
|
|
836
|
+
permlink: 'bar361',
|
|
837
|
+
last_update: '2021-10-23T09:15:21',
|
|
838
|
+
body: 'this is link /@demo/test for internal'
|
|
839
|
+
}
|
|
840
|
+
const expected = '<p><span>this is link <a class=\"markdown-post-link\" data-author=\"demo\" data-tag=\"post\" data-permlink=\"test\">@demo/test</a> for internal</span></p>'
|
|
841
|
+
|
|
842
|
+
expect(markdown2Html(input)).toBe(expected)
|
|
843
|
+
})
|
|
844
|
+
|
|
845
|
+
it('62 - Should username with permlink new line', () => {
|
|
846
|
+
const input = {
|
|
847
|
+
author: 'foo362',
|
|
848
|
+
permlink: 'bar362',
|
|
849
|
+
last_update: '2021-10-23T09:15:21',
|
|
850
|
+
body: '@demo/test for internal'
|
|
851
|
+
}
|
|
852
|
+
const expected = '<p><span> <a class=\"markdown-post-link\" data-author=\"demo\" data-tag=\"post\" data-permlink=\"test\">@demo/test</a> for internal</span></p>'
|
|
853
|
+
|
|
854
|
+
expect(markdown2Html(input)).toBe(expected)
|
|
855
|
+
})
|
|
856
|
+
|
|
857
|
+
it('63 - Should username with permlink with slash new line', () => {
|
|
858
|
+
const input = {
|
|
859
|
+
author: 'foo363',
|
|
860
|
+
permlink: 'bar363',
|
|
861
|
+
last_update: '2021-10-23T09:15:21',
|
|
862
|
+
body: '/@demo/test for internal'
|
|
863
|
+
}
|
|
864
|
+
const expected = '<p><span> <a class=\"markdown-post-link\" data-author=\"demo\" data-tag=\"post\" data-permlink=\"test\">@demo/test</a> for internal</span></p>'
|
|
865
|
+
|
|
866
|
+
expect(markdown2Html(input)).toBe(expected)
|
|
867
|
+
})
|
|
808
868
|
})
|
|
809
869
|
|
|
810
870
|
describe("Rumble support", () => {
|
|
@@ -832,7 +892,7 @@ describe('Markdown2Html', () => {
|
|
|
832
892
|
expect(markdown2Html(input)).toBe(expected)
|
|
833
893
|
})
|
|
834
894
|
|
|
835
|
-
// The following
|
|
895
|
+
// The following cannot be done: Convert URLs to the video page like this one
|
|
836
896
|
// (https://rumble.com/vkhkzl-helping-my-girls-to-cool-down-in-the-heat.html)
|
|
837
897
|
// to its corresponding embedded URL (https://rumble.com/embed/vhveub/?pub=4).
|
|
838
898
|
// The relationship seems to be governed by a table.
|
package/src/methods/a.method.ts
CHANGED
|
@@ -119,16 +119,18 @@ export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
|
119
119
|
if (mentionMatch && WHITE_LIST.includes(mentionMatch[1].replace(/www./,'')) && mentionMatch.length === 3) {
|
|
120
120
|
el.setAttribute('class', 'markdown-author-link')
|
|
121
121
|
const author = mentionMatch[2].replace('@', '').toLowerCase()
|
|
122
|
-
if (
|
|
123
|
-
el.textContent
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
122
|
+
if (author.indexOf('/')===-1) {
|
|
123
|
+
if (el.textContent === href) {
|
|
124
|
+
el.textContent = `@${author}`
|
|
125
|
+
}
|
|
126
|
+
if (forApp) {
|
|
127
|
+
el.removeAttribute('href')
|
|
128
|
+
|
|
129
|
+
el.setAttribute('data-author', author)
|
|
130
|
+
} else {
|
|
131
|
+
const h = `/@${author}`
|
|
132
|
+
el.setAttribute('href', h)
|
|
133
|
+
}
|
|
132
134
|
}
|
|
133
135
|
return
|
|
134
136
|
}
|
|
@@ -138,19 +140,19 @@ export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
|
138
140
|
if (
|
|
139
141
|
(tpostMatch && WHITE_LIST.includes(tpostMatch[1].substring(1))) || (tpostMatch && tpostMatch.length === 4 && tpostMatch[1].indexOf('/') !== 0)
|
|
140
142
|
) {
|
|
141
|
-
if (['wallet', 'feed', 'followers', 'following', 'points', 'communities', 'posts', 'blog', 'comments', 'replies', 'settings'].includes(tpostMatch[3])) {
|
|
143
|
+
if (['wallet', 'feed', 'followers', 'following', 'points', 'communities', 'posts', 'blog', 'comments', 'replies', 'settings', 'engine'].includes(tpostMatch[3])) {
|
|
142
144
|
el.setAttribute('class', 'markdown-profile-link')
|
|
143
145
|
const author = tpostMatch[2].replace('@', '').toLowerCase()
|
|
144
146
|
const section = tpostMatch[3]
|
|
145
147
|
|
|
146
148
|
if (el.textContent === href) {
|
|
147
|
-
el.textContent =
|
|
149
|
+
el.textContent = `@${author}/${section}`
|
|
148
150
|
}
|
|
149
151
|
if (forApp) {
|
|
150
152
|
const ha = `https://ecency.com/@${author}/${section}`
|
|
151
153
|
el.setAttribute('href', ha)
|
|
152
154
|
} else {
|
|
153
|
-
const h =
|
|
155
|
+
const h = `@${author}/${section}`
|
|
154
156
|
el.setAttribute('href', h)
|
|
155
157
|
}
|
|
156
158
|
return
|
|
@@ -165,7 +167,7 @@ export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
|
165
167
|
const author = tpostMatch[2].replace('@', '')
|
|
166
168
|
const permlink = tpostMatch[3]
|
|
167
169
|
if (el.textContent === href) {
|
|
168
|
-
el.textContent =
|
|
170
|
+
el.textContent = `@${author}/${permlink}`
|
|
169
171
|
}
|
|
170
172
|
if (forApp) {
|
|
171
173
|
el.removeAttribute('href')
|
|
@@ -186,16 +188,18 @@ export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
|
186
188
|
if (imentionMatch) {
|
|
187
189
|
el.setAttribute('class', 'markdown-author-link')
|
|
188
190
|
const author = imentionMatch[0].replace('/@', '').toLowerCase()
|
|
189
|
-
if (
|
|
190
|
-
el.textContent
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
if (author.indexOf('/')===-1) {
|
|
192
|
+
if (el.textContent === href) {
|
|
193
|
+
el.textContent = `@${author}`
|
|
194
|
+
}
|
|
195
|
+
if (forApp) {
|
|
196
|
+
el.removeAttribute('href')
|
|
194
197
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
198
|
+
el.setAttribute('data-author', author)
|
|
199
|
+
} else {
|
|
200
|
+
const h = `/@${author}`
|
|
201
|
+
el.setAttribute('href', h)
|
|
202
|
+
}
|
|
199
203
|
}
|
|
200
204
|
return
|
|
201
205
|
}
|
|
@@ -205,7 +209,7 @@ export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
|
205
209
|
if (
|
|
206
210
|
(cpostMatch && cpostMatch.length === 3 && cpostMatch[1].indexOf('@') === 0)
|
|
207
211
|
) {
|
|
208
|
-
if (['wallet', 'feed', 'followers', 'following', 'points', 'communities', 'posts', 'blog', 'comments', 'replies', 'settings'].includes(cpostMatch[2])) {
|
|
212
|
+
if (['wallet', 'feed', 'followers', 'following', 'points', 'communities', 'posts', 'blog', 'comments', 'replies', 'settings', 'engine'].includes(cpostMatch[2])) {
|
|
209
213
|
el.setAttribute('class', 'markdown-profile-link')
|
|
210
214
|
const author = cpostMatch[1].replace('@', '').toLowerCase()
|
|
211
215
|
const section = cpostMatch[2]
|
|
@@ -662,7 +666,12 @@ export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
|
662
666
|
el.setAttribute('data-href', href)
|
|
663
667
|
el.removeAttribute('href')
|
|
664
668
|
} else {
|
|
665
|
-
|
|
666
|
-
|
|
669
|
+
const externalRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
|
|
670
|
+
if(externalRegex.test(href)) {
|
|
671
|
+
el.setAttribute('target', '_blank');
|
|
672
|
+
el.setAttribute('rel', 'noopener');
|
|
673
|
+
} else {
|
|
674
|
+
el.setAttribute('class', 'markdown-internal-link')
|
|
675
|
+
}
|
|
667
676
|
}
|
|
668
677
|
}
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
export function cleanReply(s: string): string {
|
|
2
2
|
return (s ? s.split('\n')
|
|
3
|
-
.filter(item => item.includes('
|
|
4
|
-
.filter(item => item.includes('
|
|
5
|
-
.filter(item => item.includes('
|
|
6
|
-
.filter(item => item.includes('
|
|
7
|
-
.filter(item => item.includes('
|
|
8
|
-
.filter(item => item.includes('
|
|
9
|
-
.filter(item => item.includes('<center><sub>[
|
|
10
|
-
.filter(item => item.includes('<center><sub>
|
|
11
|
-
.filter(item => item.includes('<center>
|
|
12
|
-
.filter(item => item.includes('<center><sub>
|
|
13
|
-
.filter(item => item.includes('<center>
|
|
14
|
-
.filter(item => item.includes('<center><sub>
|
|
15
|
-
.filter(item => item.includes('
|
|
16
|
-
.filter(item => item.includes('<center><em>
|
|
17
|
-
.filter(item => item.includes('
|
|
18
|
-
.filter(item => item.includes('
|
|
19
|
-
.filter(item => item.includes('
|
|
20
|
-
.filter(item => item.includes('▶️ [
|
|
3
|
+
.filter(item => item.toLowerCase().includes('posted using [partiko') === false)
|
|
4
|
+
.filter(item => item.toLowerCase().includes('posted using [dapplr') === false)
|
|
5
|
+
.filter(item => item.toLowerCase().includes('posted using [leofinance') === false)
|
|
6
|
+
.filter(item => item.toLowerCase().includes('posted via [neoxian') === false)
|
|
7
|
+
.filter(item => item.toLowerCase().includes('posted with [stemgeeks') === false)
|
|
8
|
+
.filter(item => item.toLowerCase().includes('posted using [bilpcoin') === false)
|
|
9
|
+
.filter(item => item.toLowerCase().includes('<center><sub>[posted using aeneas.blog') === false)
|
|
10
|
+
.filter(item => item.toLowerCase().includes('<center><sub>posted via [proofofbrain.io') === false)
|
|
11
|
+
.filter(item => item.toLowerCase().includes('<center>posted on [hypnochain') === false)
|
|
12
|
+
.filter(item => item.toLowerCase().includes('<center><sub>posted via [weedcash.network') === false)
|
|
13
|
+
.filter(item => item.toLowerCase().includes('<center>posted on [naturalmedicine.io') === false)
|
|
14
|
+
.filter(item => item.toLowerCase().includes('<center><sub>posted via [musicforlife.io') === false)
|
|
15
|
+
.filter(item => item.toLowerCase().includes('if the truvvl embed is unsupported by your current frontend, click this link to view this story') === false)
|
|
16
|
+
.filter(item => item.toLowerCase().includes('<center><em>posted from truvvl') === false)
|
|
17
|
+
.filter(item => item.toLowerCase().includes('view this post <a href="https://travelfeed.io/') === false)
|
|
18
|
+
.filter(item => item.toLowerCase().includes('read this post on travelfeed.io for the best experience') === false)
|
|
19
|
+
.filter(item => item.toLowerCase().includes('posted via <a href="https://www.dporn.co/"') === false)
|
|
20
|
+
.filter(item => item.toLowerCase().includes('▶️ [watch on 3speak](https://3speak') === false)
|
|
21
|
+
.filter(item => item.toLowerCase().includes('<sup><sub>Posted via [inji.com]') === false)
|
|
22
|
+
.filter(item => item.toLowerCase().includes('view this post on [Liketu]') === false)
|
|
21
23
|
.join('\n') : '')
|
|
22
24
|
.replace('Posted via <a href="https://d.buzz" data-link="promote-link">D.Buzz</a>', '')
|
|
23
25
|
.replace('<div class="pull-right"><a href="/@hive.engage"></a></div>', '')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ARCH_REGEX, DAPPLR_REGEX, LBRY_REGEX, TRUVVL_REGEX, ODYSEE_REGEX, BITCHUTE_REGEX, RUMBLE_REGEX, BRIGHTEON_REGEX, VIMEO_EMBED_REGEX, SPEAK_EMBED_REGEX, VIMM_EMBED_REGEX, D_TUBE_EMBED_REGEX, SPOTIFY_EMBED_REGEX, SOUNDCLOUD_EMBED_REGEX, TWITCH_EMBED_REGEX, YOUTUBE_EMBED_REGEX, BRAND_NEW_TUBE_REGEX, LOOM_EMBED_REGEX } from '../consts'
|
|
1
|
+
import { ARCH_REGEX, DAPPLR_REGEX, LBRY_REGEX, TRUVVL_REGEX, ODYSEE_REGEX, BITCHUTE_REGEX, RUMBLE_REGEX, BRIGHTEON_REGEX, VIMEO_EMBED_REGEX, SPEAK_EMBED_REGEX, VIMM_EMBED_REGEX, D_TUBE_EMBED_REGEX, SPOTIFY_EMBED_REGEX, SOUNDCLOUD_EMBED_REGEX, TWITCH_EMBED_REGEX, YOUTUBE_EMBED_REGEX, BRAND_NEW_TUBE_REGEX, LOOM_EMBED_REGEX, AUREAL_EMBED_REGEX } from '../consts'
|
|
2
2
|
|
|
3
3
|
export function iframe(el: HTMLElement): void {
|
|
4
4
|
const src = el.getAttribute('src')
|
|
@@ -145,6 +145,13 @@ export function iframe(el: HTMLElement): void {
|
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
// Aureal
|
|
149
|
+
if (src.match(AUREAL_EMBED_REGEX)) {
|
|
150
|
+
el.setAttribute('src', src)
|
|
151
|
+
el.setAttribute('frameborder', '0')
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
148
155
|
const replaceNode = el.ownerDocument.createElement('div')
|
|
149
156
|
replaceNode.setAttribute('class', 'unsupported-iframe')
|
|
150
157
|
replaceNode.textContent = `(Unsupported ${src})`
|
|
@@ -16,22 +16,26 @@ export function linkify(content: string, forApp: boolean, webp: boolean): string
|
|
|
16
16
|
|
|
17
17
|
// User mentions
|
|
18
18
|
content = content.replace(
|
|
19
|
-
/(^|[^a-zA-Z0-9_!#$%&*@@/]|(^|[^a-zA-Z0-9_+~.-/]))[@@]([a-z][-.a-z\d]+[a-z\d])/gi,
|
|
19
|
+
/(^|[^a-zA-Z0-9_!#$%&*@@/]|(^|[^a-zA-Z0-9_+~.-/]))[@@]([a-z][-.a-z\d^/]+[a-z\d])/gi,
|
|
20
20
|
(match, preceeding1, preceeding2, user) => {
|
|
21
21
|
const userLower = user.toLowerCase()
|
|
22
22
|
const preceedings = (preceeding1 || '') + (preceeding2 || '')
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
if (userLower.indexOf('/')===-1) {
|
|
24
|
+
const attrs = forApp ? `data-author="${userLower}"` : `href="/@${userLower}"`
|
|
25
|
+
return `${preceedings}<a class="markdown-author-link" ${attrs}>@${user}</a>`
|
|
26
|
+
} else {
|
|
27
|
+
return match
|
|
28
|
+
}
|
|
26
29
|
}
|
|
27
30
|
)
|
|
28
31
|
|
|
29
32
|
// internal links
|
|
30
33
|
content = content.replace(
|
|
31
|
-
/(
|
|
32
|
-
const uu = u.trim().toLowerCase().replace('/@','');
|
|
33
|
-
const
|
|
34
|
-
|
|
34
|
+
/((^|\s)(\/|)@[\w.\d-]+)\/(\S+)/gi, (match, u, p1, p2, p3) => {
|
|
35
|
+
const uu = u.trim().toLowerCase().replace('/@','').replace('@','');
|
|
36
|
+
const perm = p3;
|
|
37
|
+
const attrs = forApp ? `data-author="${uu}" data-tag="post" data-permlink="${perm}"` : `href="/post/@${uu}/${perm}"`
|
|
38
|
+
return ` <a class="markdown-post-link" ${attrs}>@${uu}/${perm}</a>`
|
|
35
39
|
}
|
|
36
40
|
)
|
|
37
41
|
|