1 import { Injectable } from '@angular/core'
2 import { getAbsoluteAPIUrl } from '@app/helpers/utils'
3 import * as LinkifyJS from 'linkifyjs'
6 export class LinkifierService {
7 static CLASSNAME = 'linkified'
9 private linkifyModule: typeof LinkifyJS
10 private linkifyHtmlModule: any
12 private mentionPluginInitialized = false
14 private linkifyOptions = {
16 mention: LinkifierService.CLASSNAME + '-mention',
17 url: LinkifierService.CLASSNAME + '-url'
20 mention: (href: string) => {
21 return getAbsoluteAPIUrl() + '/services/redirect/accounts/' + href.substring(1)
26 async linkify (text: string) {
27 if (!this.linkifyModule) {
28 const result = await Promise.all([
30 import('linkify-html').then(m => (m as any).default)
33 this.linkifyModule = result[0]
34 this.linkifyHtmlModule = result[1]
36 this.buildMentionPlugin()
39 return this.linkifyHtmlModule(text, this.linkifyOptions)
42 private buildMentionPlugin () {
43 if (this.mentionPluginInitialized) return
45 const MentionToken = this.linkifyModule.createTokenClass('mention', {
48 return '/' + this.toString().slice(1)
52 this.linkifyModule.registerPlugin('mention', ({ scanner, parser }) => {
53 const { DOT, HYPHEN, UNDERSCORE, AT } = scanner.tokens
54 const { domain } = scanner.tokens.groups
57 const At = parser.start.tt(AT)
59 // Valid mention (not made up entirely of symbols)
60 const Mention = At.tt(UNDERSCORE, MentionToken as any)
62 At.ta(domain, Mention)
63 At.tt(UNDERSCORE, Mention)
65 // More valid mentions
66 Mention.ta(domain, Mention)
67 Mention.tt(HYPHEN, Mention)
68 Mention.tt(UNDERSCORE, Mention)
70 // ADDED: . transitions
71 const MentionDot = Mention.tt(DOT)
72 MentionDot.ta(domain, Mention)
73 MentionDot.tt(HYPHEN, Mention)
74 MentionDot.tt(UNDERSCORE, Mention)
76 const MentionAt = Mention.tt(AT)
77 MentionAt.ta(domain, Mention)
78 MentionAt.tt(HYPHEN, Mention)
79 MentionAt.tt(UNDERSCORE, Mention)
82 this.mentionPluginInitialized = true