]>
Commit | Line | Data |
---|---|---|
e8cb4409 | 1 | import { Injectable } from '@angular/core' |
67ed6552 | 2 | import { getAbsoluteAPIUrl } from '@app/helpers/utils' |
e81d45b4 | 3 | import * as LinkifyJS from 'linkifyjs' |
e8cb4409 C |
4 | |
5 | @Injectable() | |
6 | export class LinkifierService { | |
e8cb4409 C |
7 | static CLASSNAME = 'linkified' |
8 | ||
e81d45b4 | 9 | private linkifyModule: typeof LinkifyJS |
b355b394 C |
10 | private linkifyHtmlModule: any |
11 | ||
e81d45b4 C |
12 | private mentionPluginInitialized = false |
13 | ||
e8cb4409 C |
14 | private linkifyOptions = { |
15 | className: { | |
16 | mention: LinkifierService.CLASSNAME + '-mention', | |
17 | url: LinkifierService.CLASSNAME + '-url' | |
f8ddccf2 C |
18 | }, |
19 | formatHref: { | |
20 | mention: (href: string) => { | |
cd940f40 | 21 | return getAbsoluteAPIUrl() + '/services/redirect/accounts/' + href.substring(1) |
f8ddccf2 | 22 | } |
e8cb4409 C |
23 | } |
24 | } | |
25 | ||
b355b394 C |
26 | async linkify (text: string) { |
27 | if (!this.linkifyModule) { | |
28 | const result = await Promise.all([ | |
f8ddccf2 | 29 | import('linkifyjs'), |
f8ddccf2 | 30 | import('linkify-html').then(m => (m as any).default) |
b355b394 C |
31 | ]) |
32 | ||
33 | this.linkifyModule = result[0] | |
e81d45b4 C |
34 | this.linkifyHtmlModule = result[1] |
35 | ||
36 | this.buildMentionPlugin() | |
b355b394 | 37 | } |
e8cb4409 | 38 | |
b355b394 | 39 | return this.linkifyHtmlModule(text, this.linkifyOptions) |
e8cb4409 | 40 | } |
e81d45b4 C |
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 | } | |
e8cb4409 | 84 | } |