securemark 0.230.1 → 0.231.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/CHANGELOG.md +4 -0
- package/dist/securemark.js +18 -10
- package/package-lock.json +23 -25
- package/package.json +1 -1
- package/src/parser/inline/autolink/account.ts +1 -1
- package/src/parser/inline/autolink/email.test.ts +2 -1
- package/src/parser/inline/autolink/email.ts +1 -1
- package/src/parser/inline/autolink/hashnum.test.ts +1 -0
- package/src/parser/inline/autolink/hashnum.ts +2 -1
- package/src/parser/inline/autolink/hashtag.test.ts +13 -12
- package/src/parser/inline/autolink/hashtag.ts +9 -2
- package/src/parser/inline/autolink.ts +3 -3
- package/src/parser/inline/link.ts +1 -1
- package/src/parser/inline.test.ts +2 -0
package/CHANGELOG.md
CHANGED
package/dist/securemark.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.
|
|
1
|
+
/*! securemark v0.231.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
|
|
2
2
|
require = function () {
|
|
3
3
|
function r(e, n, t) {
|
|
4
4
|
function o(i, f) {
|
|
@@ -6257,10 +6257,10 @@ require = function () {
|
|
|
6257
6257
|
channel_1.channel,
|
|
6258
6258
|
account_1.account,
|
|
6259
6259
|
(0, source_1.str)(/^@+[0-9A-Za-z]*(?:-[0-9A-Za-z]+)*/),
|
|
6260
|
-
(0, source_1.str)(
|
|
6260
|
+
(0, source_1.str)(new RegExp(String.raw`^(?:[^\p{C}\p{S}\p{P}\s]|${ hashtag_1.emoji }|['_])(?=#)`, 'u')),
|
|
6261
6261
|
hashtag_1.hashtag,
|
|
6262
6262
|
hashnum_1.hashnum,
|
|
6263
|
-
(0, source_1.str)(
|
|
6263
|
+
(0, source_1.str)(new RegExp(String.raw`^#+(?:[^\p{C}\p{S}\p{P}\s]|${ hashtag_1.emoji }|['_])*`, 'u')),
|
|
6264
6264
|
anchor_1.anchor
|
|
6265
6265
|
])))), ns => ns.length === 1 ? ns : [(0, util_1.stringify)(ns)]);
|
|
6266
6266
|
},
|
|
@@ -6287,7 +6287,7 @@ require = function () {
|
|
|
6287
6287
|
const source_1 = _dereq_('../../source');
|
|
6288
6288
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
6289
6289
|
exports.account = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.open)('@', (0, combinator_1.tails)([
|
|
6290
|
-
(0, combinator_1.verify)((0, source_1.str)(/^[0-9A-Za-z](?:[0-9A-Za-z
|
|
6290
|
+
(0, combinator_1.verify)((0, source_1.str)(/^[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?)*\//), ([source]) => source.length <= 253 + 1),
|
|
6291
6291
|
(0, combinator_1.verify)((0, source_1.str)(/^[A-Za-z][0-9A-Za-z]*(?:-[0-9A-Za-z]+)*/), ([source]) => source.length <= 64)
|
|
6292
6292
|
])), (0, combinator_1.context)({
|
|
6293
6293
|
syntax: {
|
|
@@ -6374,7 +6374,7 @@ require = function () {
|
|
|
6374
6374
|
const combinator_1 = _dereq_('../../../combinator');
|
|
6375
6375
|
const source_1 = _dereq_('../../source');
|
|
6376
6376
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
6377
|
-
exports.email = (0, combinator_1.creator)((0, combinator_1.rewrite)((0, combinator_1.verify)((0, source_1.str)(/^[0-9A-Za-z]+(?:[.+_-][0-9A-Za-z]+)*@[0-9A-Za-z](?:[0-9A-Za-z
|
|
6377
|
+
exports.email = (0, combinator_1.creator)((0, combinator_1.rewrite)((0, combinator_1.verify)((0, source_1.str)(/^[0-9A-Za-z]+(?:[.+_-][0-9A-Za-z]+)*@[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?)*(?![0-9A-Za-z])/), ([source]) => source.indexOf('@') <= 64 && source.length <= 255), source => [
|
|
6378
6378
|
[(0, typed_dom_1.html)('a', {
|
|
6379
6379
|
class: 'email',
|
|
6380
6380
|
href: `mailto:${ source }`
|
|
@@ -6395,9 +6395,10 @@ require = function () {
|
|
|
6395
6395
|
exports.hashnum = void 0;
|
|
6396
6396
|
const combinator_1 = _dereq_('../../../combinator');
|
|
6397
6397
|
const link_1 = _dereq_('../link');
|
|
6398
|
+
const hashtag_1 = _dereq_('./hashtag');
|
|
6398
6399
|
const source_1 = _dereq_('../../source');
|
|
6399
6400
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
6400
|
-
exports.hashnum = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.open)('#', (0, source_1.str)(
|
|
6401
|
+
exports.hashnum = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.open)('#', (0, source_1.str)(new RegExp(String.raw`^[0-9]{1,16}(?![^\p{C}\p{S}\p{P}\s]|${ hashtag_1.emoji }|['_])`, 'u'))), (0, combinator_1.context)({
|
|
6401
6402
|
syntax: {
|
|
6402
6403
|
inline: {
|
|
6403
6404
|
link: true,
|
|
@@ -6413,6 +6414,7 @@ require = function () {
|
|
|
6413
6414
|
'../../../combinator': 27,
|
|
6414
6415
|
'../../source': 128,
|
|
6415
6416
|
'../link': 114,
|
|
6417
|
+
'./hashtag': 96,
|
|
6416
6418
|
'typed-dom': 26
|
|
6417
6419
|
}
|
|
6418
6420
|
],
|
|
@@ -6420,14 +6422,20 @@ require = function () {
|
|
|
6420
6422
|
function (_dereq_, module, exports) {
|
|
6421
6423
|
'use strict';
|
|
6422
6424
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
6423
|
-
exports.hashtag = void 0;
|
|
6425
|
+
exports.hashtag = exports.emoji = void 0;
|
|
6424
6426
|
const combinator_1 = _dereq_('../../../combinator');
|
|
6425
6427
|
const link_1 = _dereq_('../link');
|
|
6426
6428
|
const source_1 = _dereq_('../../source');
|
|
6427
6429
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
6430
|
+
exports.emoji = String.raw`\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F`;
|
|
6428
6431
|
exports.hashtag = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.open)('#', (0, combinator_1.tails)([
|
|
6429
|
-
(0, combinator_1.verify)((0, source_1.str)(/^[0-9A-Za-z](?:[0-9A-Za-z
|
|
6430
|
-
(0, combinator_1.verify)((0, source_1.str)(
|
|
6432
|
+
(0, combinator_1.verify)((0, source_1.str)(/^[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?)*\//), ([source]) => source.length <= 253 + 1),
|
|
6433
|
+
(0, combinator_1.verify)((0, source_1.str)(new RegExp([
|
|
6434
|
+
'^',
|
|
6435
|
+
String.raw`(?=[0-9]{0,127}_?(?:[^\d\p{C}\p{S}\p{P}\s]|${ exports.emoji }))`,
|
|
6436
|
+
String.raw`(?:[^\p{C}\p{S}\p{P}\s]|${ exports.emoji }|_(?=[^\p{C}\p{S}\p{P}\s]|${ exports.emoji })){1,128}`,
|
|
6437
|
+
String.raw`(?!_?(?:[^\p{C}\p{S}\p{P}\s]|${ exports.emoji })|')`
|
|
6438
|
+
].join(''), 'u')), ([source]) => source.length <= 128)
|
|
6431
6439
|
])), (0, combinator_1.context)({
|
|
6432
6440
|
syntax: {
|
|
6433
6441
|
inline: {
|
|
@@ -7322,7 +7330,7 @@ require = function () {
|
|
|
7322
7330
|
switch (true) {
|
|
7323
7331
|
case uri.slice(0, 2) === '^/':
|
|
7324
7332
|
const last = host.pathname.slice(host.pathname.lastIndexOf('/') + 1);
|
|
7325
|
-
return last.includes('.') && /^[0-9]*[
|
|
7333
|
+
return last.includes('.') && /^[0-9]*[A-Za-z][0-9A-Za-z]*$/.test(last.slice(last.lastIndexOf('.') + 1)) ? `${ host.pathname.slice(0, -last.length) }${ uri.slice(2) }` : `${ host.pathname.replace(/\/?$/, '/') }${ uri.slice(2) }`;
|
|
7326
7334
|
case host.origin === source.origin && host.pathname === source.pathname:
|
|
7327
7335
|
case uri.slice(0, 2) === '//':
|
|
7328
7336
|
return uri;
|
package/package-lock.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "securemark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.231.0",
|
|
4
4
|
"lockfileVersion": 1,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"dependencies": {
|
|
@@ -349,6 +349,12 @@
|
|
|
349
349
|
"to-fast-properties": "^2.0.0"
|
|
350
350
|
}
|
|
351
351
|
},
|
|
352
|
+
"@colors/colors": {
|
|
353
|
+
"version": "1.5.0",
|
|
354
|
+
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
|
|
355
|
+
"integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
|
|
356
|
+
"dev": true
|
|
357
|
+
},
|
|
352
358
|
"@gar/promisify": {
|
|
353
359
|
"version": "1.1.3",
|
|
354
360
|
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
|
|
@@ -2056,14 +2062,6 @@
|
|
|
2056
2062
|
"dev": true,
|
|
2057
2063
|
"requires": {
|
|
2058
2064
|
"colors": "1.0.3"
|
|
2059
|
-
},
|
|
2060
|
-
"dependencies": {
|
|
2061
|
-
"colors": {
|
|
2062
|
-
"version": "1.0.3",
|
|
2063
|
-
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
|
|
2064
|
-
"integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
|
|
2065
|
-
"dev": true
|
|
2066
|
-
}
|
|
2067
2065
|
}
|
|
2068
2066
|
},
|
|
2069
2067
|
"cliui": {
|
|
@@ -2164,9 +2162,9 @@
|
|
|
2164
2162
|
"dev": true
|
|
2165
2163
|
},
|
|
2166
2164
|
"colors": {
|
|
2167
|
-
"version": "1.
|
|
2168
|
-
"resolved": "https://registry.npmjs.org/colors/-/colors-1.
|
|
2169
|
-
"integrity": "
|
|
2165
|
+
"version": "1.0.3",
|
|
2166
|
+
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
|
|
2167
|
+
"integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
|
|
2170
2168
|
"dev": true
|
|
2171
2169
|
},
|
|
2172
2170
|
"combine-source-map": {
|
|
@@ -2927,9 +2925,9 @@
|
|
|
2927
2925
|
"dev": true
|
|
2928
2926
|
},
|
|
2929
2927
|
"electron-to-chromium": {
|
|
2930
|
-
"version": "1.4.
|
|
2931
|
-
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.
|
|
2932
|
-
"integrity": "sha512-
|
|
2928
|
+
"version": "1.4.75",
|
|
2929
|
+
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.75.tgz",
|
|
2930
|
+
"integrity": "sha512-LxgUNeu3BVU7sXaKjUDD9xivocQLxFtq6wgERrutdY/yIOps3ODOZExK1jg8DTEg4U8TUCb5MLGeWFOYuxjF3Q==",
|
|
2933
2931
|
"dev": true
|
|
2934
2932
|
},
|
|
2935
2933
|
"elliptic": {
|
|
@@ -5050,9 +5048,9 @@
|
|
|
5050
5048
|
}
|
|
5051
5049
|
},
|
|
5052
5050
|
"has-symbols": {
|
|
5053
|
-
"version": "1.0.
|
|
5054
|
-
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.
|
|
5055
|
-
"integrity": "sha512-
|
|
5051
|
+
"version": "1.0.3",
|
|
5052
|
+
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
|
5053
|
+
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
|
5056
5054
|
"dev": true
|
|
5057
5055
|
},
|
|
5058
5056
|
"has-tostringtag": {
|
|
@@ -6110,15 +6108,15 @@
|
|
|
6110
6108
|
"dev": true
|
|
6111
6109
|
},
|
|
6112
6110
|
"karma": {
|
|
6113
|
-
"version": "6.3.
|
|
6114
|
-
"resolved": "https://registry.npmjs.org/karma/-/karma-6.3.
|
|
6115
|
-
"integrity": "sha512-
|
|
6111
|
+
"version": "6.3.17",
|
|
6112
|
+
"resolved": "https://registry.npmjs.org/karma/-/karma-6.3.17.tgz",
|
|
6113
|
+
"integrity": "sha512-2TfjHwrRExC8yHoWlPBULyaLwAFmXmxQrcuFImt/JsAsSZu1uOWTZ1ZsWjqQtWpHLiatJOHL5jFjXSJIgCd01g==",
|
|
6116
6114
|
"dev": true,
|
|
6117
6115
|
"requires": {
|
|
6116
|
+
"@colors/colors": "1.5.0",
|
|
6118
6117
|
"body-parser": "^1.19.0",
|
|
6119
6118
|
"braces": "^3.0.2",
|
|
6120
6119
|
"chokidar": "^3.5.1",
|
|
6121
|
-
"colors": "1.4.0",
|
|
6122
6120
|
"connect": "^3.7.0",
|
|
6123
6121
|
"di": "^0.0.1",
|
|
6124
6122
|
"dom-serialize": "^2.2.1",
|
|
@@ -7456,9 +7454,9 @@
|
|
|
7456
7454
|
}
|
|
7457
7455
|
},
|
|
7458
7456
|
"npm-check-updates": {
|
|
7459
|
-
"version": "12.
|
|
7460
|
-
"resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.
|
|
7461
|
-
"integrity": "sha512-
|
|
7457
|
+
"version": "12.5.0",
|
|
7458
|
+
"resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.0.tgz",
|
|
7459
|
+
"integrity": "sha512-nrryXO9IZdJsAIXo8LdtllrsGiTDE4IMAod7fl1jd5C38tOdZZG/crNNii4IkctxltQRmK/ziZwsMDTlhszZXg==",
|
|
7462
7460
|
"dev": true,
|
|
7463
7461
|
"requires": {
|
|
7464
7462
|
"chalk": "^4.1.2",
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@ export const account: AutolinkParser.AccountParser = lazy(() => fmap(rewrite(
|
|
|
11
11
|
'@',
|
|
12
12
|
tails([
|
|
13
13
|
verify(
|
|
14
|
-
str(/^[0-9A-Za-z](?:[0-9A-Za-z
|
|
14
|
+
str(/^[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?)*\//),
|
|
15
15
|
([source]) => source.length <= 253 + 1),
|
|
16
16
|
verify(
|
|
17
17
|
str(/^[A-Za-z][0-9A-Za-z]*(?:-[0-9A-Za-z]+)*/),
|
|
@@ -23,6 +23,7 @@ describe('Unit: parser/inline/autolink/email', () => {
|
|
|
23
23
|
assert.deepStrictEqual(inspect(parser('a+@b')), undefined);
|
|
24
24
|
assert.deepStrictEqual(inspect(parser('a..b@c')), undefined);
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('a++b@c')), undefined);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser(`a@${'b'.repeat(64)}`)), [[`a@${'b'.repeat(64)}`], '']);
|
|
26
27
|
assert.deepStrictEqual(inspect(parser(' a@b')), undefined);
|
|
27
28
|
});
|
|
28
29
|
|
|
@@ -36,7 +37,7 @@ describe('Unit: parser/inline/autolink/email', () => {
|
|
|
36
37
|
assert.deepStrictEqual(inspect(parser('a@b_c')), [['<a class="email" href="mailto:a@b">a@b</a>'], '_c']);
|
|
37
38
|
assert.deepStrictEqual(inspect(parser('a@b-')), [['<a class="email" href="mailto:a@b">a@b</a>'], '-']);
|
|
38
39
|
assert.deepStrictEqual(inspect(parser('a@b-c')), [['<a class="email" href="mailto:a@b-c">a@b-c</a>'], '']);
|
|
39
|
-
assert.deepStrictEqual(inspect(parser('a@b--c')), [['<a class="email" href="mailto:a@b
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('a@b--c')), [['<a class="email" href="mailto:a@b">a@b</a>'], '--c']);
|
|
40
41
|
assert.deepStrictEqual(inspect(parser('a@b.')), [['<a class="email" href="mailto:a@b">a@b</a>'], '.']);
|
|
41
42
|
assert.deepStrictEqual(inspect(parser('a@b.c')), [['<a class="email" href="mailto:a@b.c">a@b.c</a>'], '']);
|
|
42
43
|
assert.deepStrictEqual(inspect(parser('a@b..c')), [['<a class="email" href="mailto:a@b">a@b</a>'], '..c']);
|
|
@@ -6,6 +6,6 @@ import { html } from 'typed-dom';
|
|
|
6
6
|
// https://html.spec.whatwg.org/multipage/input.html
|
|
7
7
|
|
|
8
8
|
export const email: AutolinkParser.EmailParser = creator(rewrite(verify(
|
|
9
|
-
str(/^[0-9A-Za-z]+(?:[.+_-][0-9A-Za-z]+)*@[0-9A-Za-z](?:[0-9A-Za-z
|
|
9
|
+
str(/^[0-9A-Za-z]+(?:[.+_-][0-9A-Za-z]+)*@[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?)*(?![0-9A-Za-z])/),
|
|
10
10
|
([source]) => source.indexOf('@') <= 64 && source.length <= 255),
|
|
11
11
|
source => [[html('a', { class: 'email', href: `mailto:${source}` }, source)], '']));
|
|
@@ -35,6 +35,7 @@ describe('Unit: parser/inline/autolink/hashnum', () => {
|
|
|
35
35
|
assert.deepStrictEqual(inspect(parser('あ#1')), [['あ#1'], '']);
|
|
36
36
|
assert.deepStrictEqual(inspect(parser(' #1')), undefined);
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('#12345678901234567')), [['#12345678901234567'], '']);
|
|
38
|
+
assert.deepStrictEqual(inspect(parser(`#${'1'.repeat(128)}a`)), [[`#${'1'.repeat(128)}a`], '']);
|
|
38
39
|
});
|
|
39
40
|
|
|
40
41
|
it('valid', () => {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
2
|
import { union, rewrite, context, open, convert, fmap, lazy } from '../../../combinator';
|
|
3
3
|
import { link } from '../link';
|
|
4
|
+
import { emoji } from './hashtag';
|
|
4
5
|
import { str } from '../../source';
|
|
5
6
|
import { define } from 'typed-dom';
|
|
6
7
|
|
|
7
8
|
export const hashnum: AutolinkParser.HashnumParser = lazy(() => fmap(rewrite(
|
|
8
|
-
open('#', str(
|
|
9
|
+
open('#', str(new RegExp(String.raw`^[0-9]{1,16}(?![^\p{C}\p{S}\p{P}\s]|${emoji}|['_])`, 'u'))),
|
|
9
10
|
context({ syntax: { inline: {
|
|
10
11
|
link: true,
|
|
11
12
|
autolink: false,
|
|
@@ -23,9 +23,6 @@ describe('Unit: parser/inline/autolink/hashtag', () => {
|
|
|
23
23
|
assert.deepStrictEqual(inspect(parser(`#'`)), [[`#'`], '']);
|
|
24
24
|
assert.deepStrictEqual(inspect(parser(`#a''`)), [[`#a''`], '']);
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('#_')), [['#_'], '']);
|
|
26
|
-
assert.deepStrictEqual(inspect(parser('#a_')), [['#a_'], '']);
|
|
27
|
-
assert.deepStrictEqual(inspect(parser('#a__b')), [['#a__b'], '']);
|
|
28
|
-
assert.deepStrictEqual(inspect(parser(`#a_'b`)), [[`#a_'b`], '']);
|
|
29
26
|
assert.deepStrictEqual(inspect(parser('#(a)')), [['#'], '(a)']);
|
|
30
27
|
assert.deepStrictEqual(inspect(parser('#{}')), [['#'], '{}']);
|
|
31
28
|
assert.deepStrictEqual(inspect(parser('#{{}')), [['#'], '{{}']);
|
|
@@ -38,6 +35,9 @@ describe('Unit: parser/inline/autolink/hashtag', () => {
|
|
|
38
35
|
assert.deepStrictEqual(inspect(parser('a##1')), [['a##1'], '']);
|
|
39
36
|
assert.deepStrictEqual(inspect(parser('a##b')), [['a##b'], '']);
|
|
40
37
|
assert.deepStrictEqual(inspect(parser('あ#b')), [['あ#b'], '']);
|
|
38
|
+
assert.deepStrictEqual(inspect(parser(`#${'1'.repeat(127)}_`)), [[`#${'1'.repeat(127)}_`], '']);
|
|
39
|
+
assert.deepStrictEqual(inspect(parser(`#${'1'.repeat(127)}_a`)), [[`#${'1'.repeat(127)}_a`], '']);
|
|
40
|
+
assert.deepStrictEqual(inspect(parser(`#${'1'.repeat(127)}_'a`)), [[`#${'1'.repeat(127)}_'a`], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser(' #a')), undefined);
|
|
42
42
|
});
|
|
43
43
|
|
|
@@ -50,21 +50,22 @@ describe('Unit: parser/inline/autolink/hashtag', () => {
|
|
|
50
50
|
assert.deepStrictEqual(inspect(parser('#a\\\n')), [['<a href="/hashtags/a" class="hashtag">#a</a>'], '\\\n']);
|
|
51
51
|
assert.deepStrictEqual(inspect(parser('#a)')), [['<a href="/hashtags/a" class="hashtag">#a</a>'], ')']);
|
|
52
52
|
assert.deepStrictEqual(inspect(parser('#a(b')), [['<a href="/hashtags/a" class="hashtag">#a</a>'], '(b']);
|
|
53
|
-
assert.deepStrictEqual(inspect(parser('#a(b)')), [['<a href="/hashtags/a
|
|
54
|
-
assert.deepStrictEqual(inspect(parser('#
|
|
55
|
-
assert.deepStrictEqual(inspect(parser(`#a'`)), [[`<a href="/hashtags/a'" class="hashtag">#a'</a>`], '']);
|
|
56
|
-
assert.deepStrictEqual(inspect(parser(`#a(b')`)), [[`<a href="/hashtags/a(b')" class="hashtag">#a(b')</a>`], '']);
|
|
57
|
-
assert.deepStrictEqual(inspect(parser(`#a(b'')`)), [[`<a href="/hashtags/a" class="hashtag">#a</a>`], `(b'')`]);
|
|
58
|
-
assert.deepStrictEqual(inspect(parser(`#a('b)`)), [['<a href="/hashtags/a" class="hashtag">#a</a>'], `('b)`]);
|
|
53
|
+
assert.deepStrictEqual(inspect(parser('#a(b)')), [['<a href="/hashtags/a" class="hashtag">#a</a>'], '(b)']);
|
|
54
|
+
assert.deepStrictEqual(inspect(parser('#a_')), [['<a href="/hashtags/a" class="hashtag">#a</a>'], '_']);
|
|
59
55
|
assert.deepStrictEqual(inspect(parser('#a_b')), [['<a href="/hashtags/a_b" class="hashtag">#a_b</a>'], '']);
|
|
60
|
-
assert.deepStrictEqual(inspect(parser(`#
|
|
61
|
-
assert.deepStrictEqual(inspect(parser('#
|
|
62
|
-
assert.deepStrictEqual(inspect(parser('#a(b__c)')), [['<a href="/hashtags/a" class="hashtag">#a</a>'], '(b__c)']);
|
|
56
|
+
assert.deepStrictEqual(inspect(parser(`#a_'b`)), [['<a href="/hashtags/a" class="hashtag">#a</a>'], `_'b`]);
|
|
57
|
+
assert.deepStrictEqual(inspect(parser('#a__b')), [['<a href="/hashtags/a" class="hashtag">#a</a>'], '__b']);
|
|
63
58
|
assert.deepStrictEqual(inspect(parser('#あ')), [['<a href="/hashtags/あ" class="hashtag">#あ</a>'], '']);
|
|
59
|
+
assert.deepStrictEqual(inspect(parser('#👩')), [['<a href="/hashtags/👩" class="hashtag">#👩</a>'], '']);
|
|
64
60
|
assert.deepStrictEqual(inspect(parser('#1a')), [['<a href="/hashtags/1a" class="hashtag">#1a</a>'], '']);
|
|
65
61
|
assert.deepStrictEqual(inspect(parser('#1あ')), [['<a href="/hashtags/1あ" class="hashtag">#1あ</a>'], '']);
|
|
62
|
+
assert.deepStrictEqual(inspect(parser('#1👩')), [['<a href="/hashtags/1👩" class="hashtag">#1👩</a>'], '']);
|
|
66
63
|
assert.deepStrictEqual(inspect(parser('#domain/a')), [['<a href="https://domain/hashtags/a" target="_blank" class="hashtag">#domain/a</a>'], '']);
|
|
67
64
|
assert.deepStrictEqual(inspect(parser('#domain.co.jp/a')), [['<a href="https://domain.co.jp/hashtags/a" target="_blank" class="hashtag">#domain.co.jp/a</a>'], '']);
|
|
65
|
+
// Reserved
|
|
66
|
+
assert.deepStrictEqual(inspect(parser(`#a'`)), [[`#a'`], '']);
|
|
67
|
+
assert.deepStrictEqual(inspect(parser(`#a'b`)), [[`#a'b`], '']);
|
|
68
|
+
assert.deepStrictEqual(inspect(parser(`#a'_b`)), [[`#a'_b`], '']);
|
|
68
69
|
});
|
|
69
70
|
|
|
70
71
|
});
|
|
@@ -6,15 +6,22 @@ import { define } from 'typed-dom';
|
|
|
6
6
|
|
|
7
7
|
// https://example/hashtags/a must be a hashtag page or a redirect page going there.
|
|
8
8
|
|
|
9
|
+
// https://github.com/tc39/proposal-regexp-unicode-property-escapes#matching-emoji
|
|
10
|
+
export const emoji = String.raw`\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F`;
|
|
11
|
+
|
|
9
12
|
export const hashtag: AutolinkParser.HashtagParser = lazy(() => fmap(rewrite(
|
|
10
13
|
open(
|
|
11
14
|
'#',
|
|
12
15
|
tails([
|
|
13
16
|
verify(
|
|
14
|
-
str(/^[0-9A-Za-z](?:[0-9A-Za-z
|
|
17
|
+
str(/^[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-(?=\w)){0,61}[0-9A-Za-z])?)*\//),
|
|
15
18
|
([source]) => source.length <= 253 + 1),
|
|
16
19
|
verify(
|
|
17
|
-
str(
|
|
20
|
+
str(new RegExp(['^',
|
|
21
|
+
String.raw`(?=[0-9]{0,127}_?(?:[^\d\p{C}\p{S}\p{P}\s]|${emoji}))`,
|
|
22
|
+
String.raw`(?:[^\p{C}\p{S}\p{P}\s]|${emoji}|_(?=[^\p{C}\p{S}\p{P}\s]|${emoji})){1,128}`,
|
|
23
|
+
String.raw`(?!_?(?:[^\p{C}\p{S}\p{P}\s]|${emoji})|')`,
|
|
24
|
+
].join(''), 'u')),
|
|
18
25
|
([source]) => source.length <= 128),
|
|
19
26
|
])),
|
|
20
27
|
context({ syntax: { inline: {
|
|
@@ -4,7 +4,7 @@ import { url } from './autolink/url';
|
|
|
4
4
|
import { email } from './autolink/email';
|
|
5
5
|
import { channel } from './autolink/channel';
|
|
6
6
|
import { account } from './autolink/account';
|
|
7
|
-
import { hashtag } from './autolink/hashtag';
|
|
7
|
+
import { hashtag, emoji } from './autolink/hashtag';
|
|
8
8
|
import { hashnum } from './autolink/hashnum';
|
|
9
9
|
import { anchor } from './autolink/anchor';
|
|
10
10
|
import { str } from '../source';
|
|
@@ -23,11 +23,11 @@ export const autolink: AutolinkParser = fmap(
|
|
|
23
23
|
// Escape unmatched account-like strings.
|
|
24
24
|
str(/^@+[0-9A-Za-z]*(?:-[0-9A-Za-z]+)*/),
|
|
25
25
|
// Escape invalid leading characters.
|
|
26
|
-
str(
|
|
26
|
+
str(new RegExp(String.raw`^(?:[^\p{C}\p{S}\p{P}\s]|${emoji}|['_])(?=#)`, 'u')),
|
|
27
27
|
hashtag,
|
|
28
28
|
hashnum,
|
|
29
29
|
// Escape unmatched hashtag-like strings.
|
|
30
|
-
str(
|
|
30
|
+
str(new RegExp(String.raw`^#+(?:[^\p{C}\p{S}\p{P}\s]|${emoji}|['_])*`, 'u')),
|
|
31
31
|
anchor,
|
|
32
32
|
])))),
|
|
33
33
|
ns => ns.length === 1 ? ns : [stringify(ns)]);
|
|
@@ -83,7 +83,7 @@ export function resolve(uri: string, host: URL | Location, source: URL | Locatio
|
|
|
83
83
|
case uri.slice(0, 2) === '^/':
|
|
84
84
|
const last = host.pathname.slice(host.pathname.lastIndexOf('/') + 1);
|
|
85
85
|
return last.includes('.') // isFile
|
|
86
|
-
&& /^[0-9]*[
|
|
86
|
+
&& /^[0-9]*[A-Za-z][0-9A-Za-z]*$/.test(last.slice(last.lastIndexOf('.') + 1))
|
|
87
87
|
? `${host.pathname.slice(0, -last.length)}${uri.slice(2)}`
|
|
88
88
|
: `${host.pathname.replace(/\/?$/, '/')}${uri.slice(2)}`;
|
|
89
89
|
case host.origin === source.origin
|
|
@@ -173,6 +173,7 @@ describe('Unit: parser/inline', () => {
|
|
|
173
173
|
assert.deepStrictEqual(inspect(parser('あい#b')), [['あ', 'い#b'], '']);
|
|
174
174
|
assert.deepStrictEqual(inspect(parser('0aあ#b')), [['0a', 'あ#b'], '']);
|
|
175
175
|
assert.deepStrictEqual(inspect(parser('0aあい#b')), [['0a', 'あ', 'い#b'], '']);
|
|
176
|
+
assert.deepStrictEqual(inspect(parser('「#あ」')), [['「', '<a href="/hashtags/あ" class="hashtag">#あ</a>', '」'], '']);
|
|
176
177
|
assert.deepStrictEqual(inspect(parser('a\n#b')), [['a', '<br>', '<a href="/hashtags/b" class="hashtag">#b</a>'], '']);
|
|
177
178
|
assert.deepStrictEqual(inspect(parser('a\\\n#b')), [['a', '<span class="linebreak"> </span>', '<a href="/hashtags/b" class="hashtag">#b</a>'], '']);
|
|
178
179
|
assert.deepStrictEqual(inspect(parser('*a*#b')), [['<em>a</em>', '<a href="/hashtags/b" class="hashtag">#b</a>'], '']);
|
|
@@ -186,6 +187,7 @@ describe('Unit: parser/inline', () => {
|
|
|
186
187
|
it('hashnum', () => {
|
|
187
188
|
assert.deepStrictEqual(inspect(parser('#1')), [['<a class="hashnum">#1</a>'], '']);
|
|
188
189
|
assert.deepStrictEqual(inspect(parser('#12345678901234567@a')), [['#12345678901234567@a'], '']);
|
|
190
|
+
assert.deepStrictEqual(inspect(parser('「#1」')), [['「', '<a class="hashnum">#1</a>', '」'], '']);
|
|
189
191
|
});
|
|
190
192
|
|
|
191
193
|
});
|