Skip to content

Commit b0faf14

Browse files
authored
Merge pull request #4399 from traPtitech/fix/not_mention_start_with_colon
2 parents a6f7653 + c36e5ad commit b0faf14

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

src/lib/markdown/internalLinkEmbedder.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
const urlRegexStr = '(?:https?://)?(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]+(?:/[^/]+)*/?'
77
const urlStartRegex = new RegExp(`^${urlRegexStr}`)
88
const mentionRegex = new RegExp(
9-
`(${urlRegexStr})?:?[@@]([^\\s@@.]{0,31}[^\\s@@:.])\\.?`,
9+
`(${urlRegexStr})?([@@]([^\\s@@.]{0,31}[^\\s@@:.]))\\.?|(:[@@]([^\\s@@.]{0,31}[^\\s@@:.]:))\\.?`,
1010
'g'
1111
)
1212
const userStartsRegex = /^[@]([a-zA-Z0-9_-]{1,32})/g
@@ -122,21 +122,32 @@ const replaceMention = (m: string, getters: Readonly<UserAndGroupGetters>) => {
122122
return m.replace(mentionRegex, s => {
123123
const urlStart = s.match(urlStartRegex)
124124
if (urlStart && urlStart.length !== 0) return s
125-
// 始まりが:なものを除外
126-
if (s.startsWith(':')) return s
125+
const isStartsWithColon = s.startsWith(':')
126+
127+
// 始まりと終わりが:なものを除外
128+
if (isStartsWithColon && s.endsWith(':')) {
129+
return s
130+
}
131+
127132
// 終わりが.のものを除外
128133
if (s.endsWith('.')) return s
129134

130-
// .slice(1)は先頭の@を消すため
135+
const sColonRemoved = isStartsWithColon ? s.slice(1) : s.slice(0)
136+
137+
// .slice(1)は先頭の@および:@を消すため
131138
// 小文字化はgetter内で行う
132-
const name = s.slice(1)
139+
const name = sColonRemoved.slice(1)
133140
const uid = getters.getUser(name)?.id
134141
if (uid) {
135-
return `!{"type":"user","raw":"${s}","id":"${uid}"}`
142+
return `${
143+
isStartsWithColon ? ':' : ''
144+
}!{"type":"user","raw":"${sColonRemoved}","id":"${uid}"}`
136145
}
137146
const gid = getters.getGroup(name)?.id
138147
if (gid) {
139-
return `!{"type":"group","raw":"${s}","id":"${gid}"}`
148+
return `${
149+
isStartsWithColon ? ':' : ''
150+
}!{"type":"group","raw":"${sColonRemoved}","id":"${gid}"}`
140151
}
141152

142153
return s.replace(userStartsRegex, s => {

tests/unit/lib/markdown/internalLinkEmbedder.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,22 @@ const specs: Spec[] = [
118118
'@a',
119119
'!{"type":"user","raw":"@a","id":"dfdff0c9-5de0-46ee-9721-2525e8bb3d44"}'
120120
],
121+
[
122+
':@takashi_trapo @takashi_trape',
123+
':!{"type":"group","raw":"@takashi_trapo","id":"dfabf0c9-5de0-46ee-9721-2525e8bb3d46"} !{"type":"user","raw":"@takashi_trape","id":"dfdff0c9-5de0-46ee-9721-2525e8bb3d46"}'
124+
],
125+
[
126+
':@takashi_trap',
127+
':!{"type":"user","raw":"@takashi_trap","id":"dfdff0c9-5de0-46ee-9721-2525e8bb3d45"}'
128+
],
129+
[
130+
':@takashi_trapああ',
131+
':!{"type":"user","raw":"@takashi_trap","id":"dfdff0c9-5de0-46ee-9721-2525e8bb3d45"}ああ'
132+
],
133+
[
134+
':@takashi_trap:@takashi_trap',
135+
':@takashi_trap:!{"type":"user","raw":"@takashi_trap","id":"dfdff0c9-5de0-46ee-9721-2525e8bb3d45"}'
136+
],
121137
// must not embed cases
122138
['https://example.com#a', 'https://example.com#a'],
123139
['example.com/#a', 'example.com/#a'],

0 commit comments

Comments
 (0)