]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/core/renderer/linkifier.service.ts
Fix mention detection
[github/Chocobozzz/PeerTube.git] / client / src / app / core / renderer / linkifier.service.ts
1 import { Injectable } from '@angular/core'
2 import { getAbsoluteAPIUrl } from '@app/helpers/utils'
3 import * as LinkifyJS from 'linkifyjs'
4
5 @Injectable()
6 export class LinkifierService {
7 static CLASSNAME = 'linkified'
8
9 private linkifyModule: typeof LinkifyJS
10 private linkifyHtmlModule: any
11
12 private mentionPluginInitialized = false
13
14 private linkifyOptions = {
15 className: {
16 mention: LinkifierService.CLASSNAME + '-mention',
17 url: LinkifierService.CLASSNAME + '-url'
18 },
19 formatHref: {
20 mention: (href: string) => {
21 return getAbsoluteAPIUrl() + '/services/redirect/accounts/' + href.substring(1)
22 }
23 }
24 }
25
26 async linkify (text: string) {
27 if (!this.linkifyModule) {
28 const result = await Promise.all([
29 import('linkifyjs'),
30 import('linkify-html').then(m => (m as any).default)
31 ])
32
33 this.linkifyModule = result[0]
34 this.linkifyHtmlModule = result[1]
35
36 this.buildMentionPlugin()
37 }
38
39 return this.linkifyHtmlModule(text, this.linkifyOptions)
40 }
41
42 private buildMentionPlugin () {
43 if (this.mentionPluginInitialized) return
44
45 const MentionToken = this.linkifyModule.createTokenClass('mention', {
46 isLink: true,
47 toHref () {
48 return '/' + this.toString().slice(1)
49 }
50 })
51
52 this.linkifyModule.registerPlugin('mention', ({ scanner, parser }) => {
53 const { DOT, HYPHEN, UNDERSCORE, AT } = scanner.tokens
54 const { domain } = scanner.tokens.groups
55
56 // Start with @
57 const At = parser.start.tt(AT)
58
59 // Valid mention (not made up entirely of symbols)
60 const Mention = At.tt(UNDERSCORE, MentionToken as any)
61
62 At.ta(domain, Mention)
63 At.tt(UNDERSCORE, Mention)
64
65 // More valid mentions
66 Mention.ta(domain, Mention)
67 Mention.tt(HYPHEN, Mention)
68 Mention.tt(UNDERSCORE, Mention)
69
70 // ADDED: . transitions
71 const MentionDot = Mention.tt(DOT)
72 MentionDot.ta(domain, Mention)
73 MentionDot.tt(HYPHEN, Mention)
74 MentionDot.tt(UNDERSCORE, Mention)
75
76 const MentionAt = Mention.tt(AT)
77 MentionAt.ta(domain, Mention)
78 MentionAt.tt(HYPHEN, Mention)
79 MentionAt.tt(UNDERSCORE, Mention)
80 })
81
82 this.mentionPluginInitialized = true
83 }
84 }