diff --git a/CHANGELOG.md b/CHANGELOG.md index c140bb6..40b7eb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ### Improvements ### Changes +- allow `.` in mentions (like `@bsky.brid.gy@bsky.brid.gy`) ### Bugfixes diff --git a/src/internal/parser.ts b/src/internal/parser.ts index 26029b1..5b8eac4 100644 --- a/src/internal/parser.ts +++ b/src/internal/parser.ts @@ -552,7 +552,7 @@ export const language = P.createLanguage({ const parser = P.seq( notLinkLabel, P.str('@'), - P.regexp(/[a-z0-9_-]+/i), + P.regexp(/[a-z0-9_.-]+/i), P.seq( P.str('@'), P.regexp(/[a-z0-9_.-]+/i), @@ -586,9 +586,9 @@ export const language = P.createLanguage({ } } } - // remove "-" of tail of username + // remove [.-] of tail of username let modifiedName = username; - result = /-+$/.exec(username); + result = /[.-]+$/.exec(username); if (result != null) { if (modifiedHost == null) { modifiedName = username.slice(0, (-1 * result[0].length)); @@ -597,8 +597,8 @@ export const language = P.createLanguage({ invalidMention = true; } } - // disallow "-" of head of username - if (modifiedName.length === 0 || modifiedName[0] === '-') { + // disallow [.-] of head of username + if (modifiedName.length === 0 || /^[.-]/.test(modifiedName)) { invalidMention = true; } // disallow [.-] of head of hostname diff --git a/test/parser.ts b/test/parser.ts index 852699c..36d98c3 100644 --- a/test/parser.ts +++ b/test/parser.ts @@ -733,6 +733,12 @@ hoge`; assert.deepStrictEqual(mfm.parse(input), output); }); + test('allow "." in username', () => { + const input = '@bsky.brid.gy@bsky.brid.gy'; + const output = [MENTION('bsky.brid.gy', 'bsky.brid.gy', '@bsky.brid.gy@bsky.brid.gy')]; + assert.deepStrictEqual(mfm.parse(input), output); + }); + test('disallow "-" in head of username', () => { const input = '@-abc'; const output = [TEXT('@-abc')]; @@ -745,6 +751,18 @@ hoge`; assert.deepStrictEqual(mfm.parse(input), output); }); + test('disallow "." in head of username', () => { + const input = '@.abc'; + const output = [TEXT('@.abc')]; + assert.deepStrictEqual(mfm.parse(input), output); + }); + + test('disallow "." in tail of username', () => { + const input = '@abc.'; + const output = [MENTION('abc', null, '@abc'), TEXT('.')]; + assert.deepStrictEqual(mfm.parse(input), output); + }); + test('disallow "." in head of hostname', () => { const input = '@abc@.aaa'; const output = [TEXT('@abc@.aaa')];