nodebb-plugin-mentions 4.0.6 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/library.js +8 -3
- package/package.json +2 -2
- package/test/index.js +40 -19
package/library.js
CHANGED
|
@@ -27,7 +27,12 @@ const SocketPlugins = require.main.require('./src/socket.io/plugins');
|
|
|
27
27
|
|
|
28
28
|
const utility = require('./lib/utility');
|
|
29
29
|
|
|
30
|
-
const
|
|
30
|
+
const parts = {
|
|
31
|
+
before: '(?:(^|\\p{^L}))', // a single unicode non-letter character or start of line
|
|
32
|
+
main: '(@[\\p{L}\\d\\-_.]+)', // unicode letters, numbers, dashes, underscores, or periods
|
|
33
|
+
after: '((?=\\b)(?=[^-])|$)', // used to figure out where latin mentions end
|
|
34
|
+
};
|
|
35
|
+
const regex = XRegExp(`${parts.before}${parts.main}`, 'g');
|
|
31
36
|
const isLatinMention = /@[\w\d\-_.]+$/;
|
|
32
37
|
|
|
33
38
|
const Mentions = module.exports;
|
|
@@ -293,8 +298,8 @@ Mentions.parseRaw = async (content) => {
|
|
|
293
298
|
|
|
294
299
|
if (results.user.uid || results.groupExists) {
|
|
295
300
|
const regex = isLatinMention.test(match) ?
|
|
296
|
-
|
|
297
|
-
|
|
301
|
+
XRegExp(`${parts.before}${match}${parts.after}`, 'g') :
|
|
302
|
+
XRegExp(`${parts.before}${match}`, 'g');
|
|
298
303
|
|
|
299
304
|
let skip = false;
|
|
300
305
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodebb-plugin-mentions",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "NodeBB Plugin that allows users to mention other users by prepending an '@' sign to their username",
|
|
5
5
|
"main": "library.js",
|
|
6
6
|
"scripts": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"mocha": "10.2.0",
|
|
35
|
-
"eslint": "8.
|
|
35
|
+
"eslint": "8.39.0",
|
|
36
36
|
"eslint-config-nodebb": "0.2.1",
|
|
37
37
|
"eslint-plugin-import": "2.27.5"
|
|
38
38
|
}
|
package/test/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
/* globals describe, it,
|
|
3
|
+
/* globals describe, it, beforeEach */
|
|
4
4
|
|
|
5
5
|
const assert = require('assert');
|
|
6
6
|
|
|
@@ -16,23 +16,28 @@ const regex = main._regex;
|
|
|
16
16
|
// use core slugify module
|
|
17
17
|
const slugify = require.main.require('./src/slugify');
|
|
18
18
|
|
|
19
|
+
const strings = [
|
|
20
|
+
'@testUser',
|
|
21
|
+
'@testUser some text',
|
|
22
|
+
'some text @testUser',
|
|
23
|
+
'<a href="/user/testuser">@testUser</a>',
|
|
24
|
+
'<a href="/user/testuser">@testUser</a> some text',
|
|
25
|
+
'some text <a href="/user/testuser">@testUser</a>',
|
|
26
|
+
'end of sentence. @testUser',
|
|
27
|
+
'@testUser.',
|
|
28
|
+
'@testUser\'s some text',
|
|
29
|
+
'> @testUser blockquoted',
|
|
30
|
+
'(@testUser) bracketed',
|
|
31
|
+
'elon makes me think of this emoji: 💩@testUser',
|
|
32
|
+
];
|
|
33
|
+
|
|
19
34
|
describe('regex', () => {
|
|
20
35
|
const matcher = new RegExp(regex);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'
|
|
24
|
-
'some text @testUser',
|
|
25
|
-
'<a href="/user/testuser">@testUser</a>',
|
|
26
|
-
'<a href="/user/testuser">@testUser</a> some text',
|
|
27
|
-
'some text <a href="/user/testuser">@testUser</a>',
|
|
28
|
-
'end of sentence. @testUser',
|
|
29
|
-
'@testUser.',
|
|
30
|
-
'@testUser\'s some text',
|
|
31
|
-
];
|
|
32
|
-
it('should match a mention in all strings', () => {
|
|
33
|
-
strings.forEach((string) => {
|
|
36
|
+
|
|
37
|
+
strings.forEach((string) => {
|
|
38
|
+
it('should match a mention in all test strings', () => {
|
|
34
39
|
const matches = string.match(matcher);
|
|
35
|
-
assert(matches);
|
|
40
|
+
assert(matches, `@testUser was not found in this string: ${string}`);
|
|
36
41
|
assert.equal(slugify(matches[0]), 'testuser');
|
|
37
42
|
});
|
|
38
43
|
});
|
|
@@ -152,19 +157,35 @@ describe('splitter', () => {
|
|
|
152
157
|
|
|
153
158
|
describe('parser', () => {
|
|
154
159
|
let slug;
|
|
160
|
+
let uid;
|
|
155
161
|
|
|
156
|
-
|
|
162
|
+
beforeEach(async () => {
|
|
157
163
|
slug = utils.generateUUID().slice(0, 10);
|
|
158
|
-
await
|
|
159
|
-
await user.create({ username });
|
|
160
|
-
}));
|
|
164
|
+
uid = await user.create({ username: slug });
|
|
161
165
|
});
|
|
162
166
|
|
|
163
167
|
it('should properly parse both users even if one user\'s username is a subset of the other', async () => {
|
|
168
|
+
await user.create({ username: `${slug}-two` });
|
|
164
169
|
const md = `This sentence contains two mentions: @${slug} and @${slug}-two`;
|
|
165
170
|
|
|
166
171
|
const html = await main.parseRaw(md);
|
|
167
172
|
|
|
168
173
|
assert.strictEqual(html, `This sentence contains two mentions: <a class="plugin-mentions-user plugin-mentions-a" href="http://127.0.0.1:4567/uid/1">@${slug}</a> and <a class="plugin-mentions-user plugin-mentions-a" href="http://127.0.0.1:4567/uid/2">@${slug}-two</a>`);
|
|
169
174
|
});
|
|
175
|
+
|
|
176
|
+
strings.forEach((string) => {
|
|
177
|
+
it('should match correctly replace the mentions in all test strings', async () => {
|
|
178
|
+
const index = string.indexOf('@testUser');
|
|
179
|
+
let check = string;
|
|
180
|
+
if (!index || string[index - 1] !== '>') {
|
|
181
|
+
check = string.replace(/@testUser/g, `<a class="plugin-mentions-user plugin-mentions-a" href="http://127.0.0.1:4567/uid/${uid}">@${slug}</a>`);
|
|
182
|
+
string = string.replace(/testUser/g, slug);
|
|
183
|
+
}
|
|
184
|
+
const html = await main.parseRaw(string);
|
|
185
|
+
|
|
186
|
+
assert(html);
|
|
187
|
+
|
|
188
|
+
assert.strictEqual(html, check);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
170
191
|
});
|