securemark 0.264.0 → 0.265.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 +5 -0
- package/dist/index.js +22 -42
- package/package.json +1 -1
- package/src/combinator/data/parser/some.ts +2 -1
- package/src/parser/api/normalize.ts +1 -1
- package/src/parser/block/blockquote.ts +1 -1
- package/src/parser/block/extension/aside.ts +0 -2
- package/src/parser/block/extension/figure.test.ts +2 -2
- package/src/parser/block/olist.test.ts +27 -25
- package/src/parser/block/sidefence.ts +1 -1
- package/src/parser/block/ulist.test.ts +23 -23
- package/src/parser/inline/extension/indexee.ts +5 -7
- package/src/parser/inline/link.test.ts +26 -22
- package/src/parser/inline/link.ts +9 -14
- package/src/parser/inline.test.ts +3 -2
- package/src/parser/processor/figure.ts +0 -2
- package/src/parser/processor/footnote.ts +0 -4
- package/src/util/toc.ts +0 -2
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.
|
|
1
|
+
/*! securemark v0.265.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
|
|
2
2
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
3
3
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
4
4
|
module.exports = factory(require("Prism"), require("DOMPurify"));
|
|
@@ -4151,7 +4151,7 @@ function format(source) {
|
|
|
4151
4151
|
return source.replace(/\r\n?/g, '\n');
|
|
4152
4152
|
}
|
|
4153
4153
|
function sanitize(source) {
|
|
4154
|
-
return source.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]|[\u2006\u200B-\u200F\u202A-\u202F\u2060\uFEFF]|(
|
|
4154
|
+
return source.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]|[\u2006\u200B-\u200F\u202A-\u202F\u2060\uFEFF]|(?<![\u1820\u1821])\u180E/g, UNICODE_REPLACEMENT_CHARACTER).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]?|[\uDC00-\uDFFF]/g, char => char.length === 1 ? UNICODE_REPLACEMENT_CHARACTER : char);
|
|
4155
4155
|
}
|
|
4156
4156
|
// https://dev.w3.org/html5/html-author/charref
|
|
4157
4157
|
// https://en.wikipedia.org/wiki/Whitespace_character
|
|
@@ -4263,7 +4263,7 @@ exports.parse = parse;
|
|
|
4263
4263
|
|
|
4264
4264
|
/***/ }),
|
|
4265
4265
|
|
|
4266
|
-
/***/
|
|
4266
|
+
/***/ 7185:
|
|
4267
4267
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
4268
4268
|
|
|
4269
4269
|
"use strict";
|
|
@@ -4366,7 +4366,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
4366
4366
|
}));
|
|
4367
4367
|
exports.blockquote = exports.segment = void 0;
|
|
4368
4368
|
const combinator_1 = __webpack_require__(2087);
|
|
4369
|
-
const autolink_1 = __webpack_require__(
|
|
4369
|
+
const autolink_1 = __webpack_require__(7185);
|
|
4370
4370
|
const source_1 = __webpack_require__(6743);
|
|
4371
4371
|
const parse_1 = __webpack_require__(5013);
|
|
4372
4372
|
const dom_1 = __webpack_require__(3252);
|
|
@@ -4374,7 +4374,7 @@ exports.segment = (0, combinator_1.block)((0, combinator_1.validate)(['!>', '>']
|
|
|
4374
4374
|
exports.blockquote = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.union)([(0, combinator_1.open)(/^(?=>)/, source), (0, combinator_1.open)(/^!(?=>)/, markdown)]))));
|
|
4375
4375
|
const opener = /^(?=>>+(?:$|\s))/;
|
|
4376
4376
|
const indent = (0, combinator_1.block)((0, combinator_1.open)(opener, (0, combinator_1.some)(source_1.contentline, /^>(?:$|\s)/)), false);
|
|
4377
|
-
const unindent = source => source.replace(/(
|
|
4377
|
+
const unindent = source => source.replace(/(?<=^|\n)>(?:[^\S\n]|(?=>*(?:$|\s)))|\n$/g, '');
|
|
4378
4378
|
const source = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.creation)(1, false, (0, combinator_1.union)([(0, combinator_1.rewrite)(indent, (0, combinator_1.convert)(unindent, source)), (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.contentline, opener), (0, combinator_1.convert)(unindent, (0, combinator_1.fmap)((0, combinator_1.some)(autolink_1.autolink), ns => [(0, dom_1.html)('pre', (0, dom_1.defrag)(ns))])))]))), ns => [(0, dom_1.html)('blockquote', ns)]));
|
|
4379
4379
|
const markdown = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.creation)(1, false, (0, combinator_1.union)([(0, combinator_1.rewrite)(indent, (0, combinator_1.convert)(unindent, markdown)), (0, combinator_1.creation)(99, false, (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.contentline, opener), (0, combinator_1.convert)(unindent, ({
|
|
4380
4380
|
source,
|
|
@@ -4406,7 +4406,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
4406
4406
|
exports.codeblock = exports.segment_ = exports.segment = void 0;
|
|
4407
4407
|
const parser_1 = __webpack_require__(6728);
|
|
4408
4408
|
const combinator_1 = __webpack_require__(2087);
|
|
4409
|
-
const autolink_1 = __webpack_require__(
|
|
4409
|
+
const autolink_1 = __webpack_require__(7185);
|
|
4410
4410
|
const dom_1 = __webpack_require__(3252);
|
|
4411
4411
|
const opener = /^(`{3,})(?!`)([^\n]*)(?:$|\n)/;
|
|
4412
4412
|
const language = /^[0-9a-z]+(?:-[a-z][0-9a-z]*)*$/i;
|
|
@@ -4539,8 +4539,6 @@ exports.aside = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, co
|
|
|
4539
4539
|
references
|
|
4540
4540
|
}
|
|
4541
4541
|
}, context);
|
|
4542
|
-
// Bug: Firefox
|
|
4543
|
-
//const heading = document.querySelector(':scope > h1:first-child');
|
|
4544
4542
|
const heading = 'H1 H2 H3 H4 H5 H6'.split(' ').includes(document.firstElementChild?.tagName) && document.firstElementChild;
|
|
4545
4543
|
if (!heading) return [(0, dom_1.html)('pre', {
|
|
4546
4544
|
class: 'invalid',
|
|
@@ -5455,7 +5453,7 @@ const parser_1 = __webpack_require__(6728);
|
|
|
5455
5453
|
const combinator_1 = __webpack_require__(2087);
|
|
5456
5454
|
const math_1 = __webpack_require__(8946);
|
|
5457
5455
|
const source_1 = __webpack_require__(6743);
|
|
5458
|
-
const autolink_1 = __webpack_require__(
|
|
5456
|
+
const autolink_1 = __webpack_require__(7185);
|
|
5459
5457
|
const dom_1 = __webpack_require__(3252);
|
|
5460
5458
|
exports.syntax = /^>+(?=[^\S\n])|^>(?=[^\s>])|^>+(?=[^\s>])(?![0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:]))/;
|
|
5461
5459
|
exports.quote = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, false, (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.validate)('>', (0, combinator_1.union)([(0, combinator_1.rewrite)((0, combinator_1.some)((0, combinator_1.validate)(new RegExp(exports.syntax.source.split('|')[0]), source_1.anyline)), qblock), (0, combinator_1.rewrite)((0, combinator_1.validate)(new RegExp(exports.syntax.source.split('|').slice(1).join('|')), source_1.anyline), (0, combinator_1.line)((0, combinator_1.union)([(0, source_1.str)(/^.+/)])))])), ns => [(0, dom_1.html)('span', ns.length > 1 ? {
|
|
@@ -5516,7 +5514,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
5516
5514
|
}));
|
|
5517
5515
|
exports.sidefence = void 0;
|
|
5518
5516
|
const combinator_1 = __webpack_require__(2087);
|
|
5519
|
-
const autolink_1 = __webpack_require__(
|
|
5517
|
+
const autolink_1 = __webpack_require__(7185);
|
|
5520
5518
|
const source_1 = __webpack_require__(6743);
|
|
5521
5519
|
const dom_1 = __webpack_require__(3252);
|
|
5522
5520
|
exports.sidefence = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.focus)(/^(?=\|+(?:[^\S\n]|\n\|))(?:\|+(?:[^\S\n][^\n]*)?(?:$|\n))+$/, (0, combinator_1.union)([source])), ([el]) => [(0, dom_1.define)(el, {
|
|
@@ -5526,7 +5524,7 @@ exports.sidefence = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, com
|
|
|
5526
5524
|
'data-invalid-message': 'Reserved syntax'
|
|
5527
5525
|
})])));
|
|
5528
5526
|
const opener = /^(?=\|\|+(?:$|\s))/;
|
|
5529
|
-
const unindent = source => source.replace(/(
|
|
5527
|
+
const unindent = source => source.replace(/(?<=^|\n)\|(?:[^\S\n]|(?=\|*(?:$|\s)))|\n$/g, '');
|
|
5530
5528
|
const source = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.creation)(1, false, (0, combinator_1.union)([(0, combinator_1.focus)(/^(?:\|\|+(?:[^\S\n][^\n]*)?(?:$|\n))+/, (0, combinator_1.convert)(unindent, source)), (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.contentline, opener), (0, combinator_1.convert)(unindent, (0, combinator_1.fmap)((0, combinator_1.some)(autolink_1.autolink), ns => [(0, dom_1.html)('pre', (0, dom_1.defrag)(ns))])))]))), ns => [(0, dom_1.html)('blockquote', ns)]));
|
|
5531
5529
|
|
|
5532
5530
|
/***/ }),
|
|
@@ -5687,7 +5685,7 @@ const insertion_1 = __webpack_require__(2945);
|
|
|
5687
5685
|
const deletion_1 = __webpack_require__(7501);
|
|
5688
5686
|
const mark_1 = __webpack_require__(2480);
|
|
5689
5687
|
const emphasis_1 = __webpack_require__(3867);
|
|
5690
|
-
const strong_1 = __webpack_require__(
|
|
5688
|
+
const strong_1 = __webpack_require__(6578);
|
|
5691
5689
|
const code_1 = __webpack_require__(5771);
|
|
5692
5690
|
const media_1 = __webpack_require__(1303);
|
|
5693
5691
|
const htmlentity_1 = __webpack_require__(1562);
|
|
@@ -6145,29 +6143,27 @@ function identity(text, name = 'index') {
|
|
|
6145
6143
|
exports.identity = identity;
|
|
6146
6144
|
function text(source, optional = false) {
|
|
6147
6145
|
const indexer = source.querySelector(':scope > .indexer');
|
|
6148
|
-
if (!indexer && optional) return '';
|
|
6149
6146
|
const index = indexer?.getAttribute('data-index');
|
|
6150
6147
|
if (index) return index;
|
|
6148
|
+
if (index === '' && optional) return '';
|
|
6151
6149
|
const target = source.cloneNode(true);
|
|
6152
6150
|
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .comment, rt, rp, br, .annotation, .reference, .checkbox, ul, ol'), len = es.length, i = 0; i < len; ++i) {
|
|
6153
6151
|
const el = es[i];
|
|
6154
6152
|
switch (el.tagName) {
|
|
6155
6153
|
case 'CODE':
|
|
6156
|
-
|
|
6154
|
+
el.replaceWith(el.getAttribute('data-src'));
|
|
6157
6155
|
continue;
|
|
6158
6156
|
case 'RT':
|
|
6159
6157
|
case 'RP':
|
|
6158
|
+
case 'BR':
|
|
6160
6159
|
case 'UL':
|
|
6161
6160
|
case 'OL':
|
|
6162
6161
|
el.remove();
|
|
6163
6162
|
continue;
|
|
6164
|
-
case 'BR':
|
|
6165
|
-
el.replaceWith('\n');
|
|
6166
|
-
continue;
|
|
6167
6163
|
}
|
|
6168
6164
|
switch (el.className) {
|
|
6169
6165
|
case 'math':
|
|
6170
|
-
|
|
6166
|
+
el.replaceWith(el.getAttribute('data-src'));
|
|
6171
6167
|
continue;
|
|
6172
6168
|
case 'comment':
|
|
6173
6169
|
case 'checkbox':
|
|
@@ -6411,11 +6407,9 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
6411
6407
|
value: true
|
|
6412
6408
|
}));
|
|
6413
6409
|
exports.resolve = exports.option = exports.uri = exports.unsafelink = exports.link = void 0;
|
|
6414
|
-
const parser_1 = __webpack_require__(6728);
|
|
6415
6410
|
const combinator_1 = __webpack_require__(2087);
|
|
6416
6411
|
const inline_1 = __webpack_require__(1160);
|
|
6417
6412
|
const html_1 = __webpack_require__(5994);
|
|
6418
|
-
const autolink_1 = __webpack_require__(6578);
|
|
6419
6413
|
const source_1 = __webpack_require__(6743);
|
|
6420
6414
|
const visibility_1 = __webpack_require__(7618);
|
|
6421
6415
|
const util_1 = __webpack_require__(9437);
|
|
@@ -6433,22 +6427,11 @@ const medialink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(16 /
|
|
|
6433
6427
|
exports.unsafelink = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(10, (0, combinator_1.precedence)(2, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([source_1.unescsource]), ']'), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => parse(content, params, rest, context)))));
|
|
6434
6428
|
exports.uri = (0, combinator_1.union)([(0, combinator_1.open)(/^[^\S\n]+/, (0, source_1.str)(/^\S+/)), (0, source_1.str)(/^[^\s{}]+/)]);
|
|
6435
6429
|
exports.option = (0, combinator_1.union)([(0, combinator_1.fmap)((0, source_1.str)(/^[^\S\n]+nofollow(?=[^\S\n]|})/), () => [` rel="nofollow"`]), (0, source_1.str)(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|})/), (0, combinator_1.fmap)((0, source_1.str)(/^[^\S\n]+[^\s{}]+/), opt => [` \\${opt.slice(1)}`])]);
|
|
6436
|
-
const autolink = (0, combinator_1.state)(2 /* State.autolink */, false, (0, combinator_1.state)(1 /* State.shortcut */, autolink_1.autolink));
|
|
6437
6430
|
function parse(content, params, rest, context) {
|
|
6438
6431
|
if (content.length !== 0 && (0, visibility_1.trimNode)(content).length === 0) return;
|
|
6439
|
-
content = (0, dom_1.defrag)(content);
|
|
6440
|
-
for (let source = (0, util_1.stringify)(content); source;) {
|
|
6441
|
-
if (/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i.test(source)) return;
|
|
6442
|
-
const result = autolink({
|
|
6443
|
-
source,
|
|
6444
|
-
context
|
|
6445
|
-
});
|
|
6446
|
-
if (typeof (0, parser_1.eval)(result, [])[0] === 'object') return;
|
|
6447
|
-
source = (0, parser_1.exec)(result, '');
|
|
6448
|
-
}
|
|
6449
6432
|
const INSECURE_URI = params.shift();
|
|
6450
6433
|
const uri = new url_1.ReadonlyURL(resolve(INSECURE_URI, context.host ?? location, context.url ?? context.host ?? location), context.host?.href || location.href);
|
|
6451
|
-
const el = elem(INSECURE_URI, content, uri, context.host?.origin || location.origin);
|
|
6434
|
+
const el = elem(INSECURE_URI, (0, dom_1.defrag)(content), uri, context.host?.origin || location.origin);
|
|
6452
6435
|
if (el.className === 'invalid') return [[el], rest];
|
|
6453
6436
|
return [[(0, dom_1.define)(el, (0, html_1.attributes)('link', [], optspec, params))], rest];
|
|
6454
6437
|
}
|
|
@@ -6459,6 +6442,10 @@ function elem(INSECURE_URI, content, uri, origin) {
|
|
|
6459
6442
|
case 'http:':
|
|
6460
6443
|
case 'https:':
|
|
6461
6444
|
switch (true) {
|
|
6445
|
+
case /[a-z][0-9]*:\/{0,2}\S/i.test((0, util_1.stringify)(content)):
|
|
6446
|
+
type = 'content';
|
|
6447
|
+
message = 'URI must not be contained';
|
|
6448
|
+
break;
|
|
6462
6449
|
case INSECURE_URI.slice(0, 2) === '^/' && /\/\.\.?(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/))):
|
|
6463
6450
|
type = 'argument';
|
|
6464
6451
|
message = 'Dot-segments cannot be used in subresource paths';
|
|
@@ -6484,6 +6471,7 @@ function elem(INSECURE_URI, content, uri, origin) {
|
|
|
6484
6471
|
type = 'content';
|
|
6485
6472
|
message = 'Invalid content';
|
|
6486
6473
|
}
|
|
6474
|
+
break;
|
|
6487
6475
|
}
|
|
6488
6476
|
return (0, dom_1.html)('a', {
|
|
6489
6477
|
class: 'invalid',
|
|
@@ -6512,7 +6500,7 @@ function decode(uri) {
|
|
|
6512
6500
|
const origin = uri.match(/^[a-z](?:[-.](?=\w)|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i)?.[0] ?? '';
|
|
6513
6501
|
try {
|
|
6514
6502
|
let path = decodeURI(uri.slice(origin.length));
|
|
6515
|
-
if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])
|
|
6503
|
+
if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])*:\/{0,2}\S/i.test(path)) {
|
|
6516
6504
|
path = uri.slice(origin.length);
|
|
6517
6505
|
}
|
|
6518
6506
|
uri = origin + path;
|
|
@@ -6831,7 +6819,7 @@ exports.shortmedia = (0, combinator_1.rewrite)((0, combinator_1.constraint)(8 /*
|
|
|
6831
6819
|
|
|
6832
6820
|
/***/ }),
|
|
6833
6821
|
|
|
6834
|
-
/***/
|
|
6822
|
+
/***/ 6578:
|
|
6835
6823
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
6836
6824
|
|
|
6837
6825
|
"use strict";
|
|
@@ -6894,8 +6882,6 @@ function* figure(target, footnotes, opts = {}) {
|
|
|
6894
6882
|
let base = '0';
|
|
6895
6883
|
let bases = base.split('.');
|
|
6896
6884
|
let index = bases;
|
|
6897
|
-
// Bug: Firefox
|
|
6898
|
-
//for (let defs = target.querySelectorAll(':scope > figure[data-label], :scope > h1, :scope > h2'), len = defs.length, i = 0; i < len; ++i) {
|
|
6899
6885
|
for (let defs = target.querySelectorAll('figure[data-label], h1, h2'), len = defs.length, i = 0; i < len; ++i) {
|
|
6900
6886
|
yield;
|
|
6901
6887
|
const def = defs[i];
|
|
@@ -7056,8 +7042,6 @@ const indexee_1 = __webpack_require__(1269);
|
|
|
7056
7042
|
const queue_1 = __webpack_require__(4934);
|
|
7057
7043
|
const dom_1 = __webpack_require__(3252);
|
|
7058
7044
|
function* footnote(target, footnotes, opts = {}, bottom = null) {
|
|
7059
|
-
// Bug: Firefox
|
|
7060
|
-
//target.querySelectorAll(`:scope > .annotations`).forEach(el => el.remove());
|
|
7061
7045
|
for (let es = target.querySelectorAll(`.annotations`), len = es.length, i = 0; i < len; ++i) {
|
|
7062
7046
|
const el = es[i];
|
|
7063
7047
|
el.parentNode === target && el.remove();
|
|
@@ -7076,8 +7060,6 @@ function build(syntax, marker, splitter) {
|
|
|
7076
7060
|
const defs = new Map();
|
|
7077
7061
|
const buffer = new queue_1.MultiQueue();
|
|
7078
7062
|
const titles = new Map();
|
|
7079
|
-
// Bug: Firefox
|
|
7080
|
-
//const splitters = push([], target.querySelectorAll(`:scope > :is(${splitter ?? '_'})`));
|
|
7081
7063
|
const splitters = [];
|
|
7082
7064
|
for (let es = target.querySelectorAll(splitter ?? '_'), len = es.length, i = 0; i < len; ++i) {
|
|
7083
7065
|
const el = es[i];
|
|
@@ -8331,8 +8313,6 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
8331
8313
|
exports.toc = void 0;
|
|
8332
8314
|
const array_1 = __webpack_require__(8112);
|
|
8333
8315
|
const dom_1 = __webpack_require__(3252);
|
|
8334
|
-
// Bug: Firefox
|
|
8335
|
-
//const selector = `:scope > :is(h1, h2, h3, h4, h5, h6, aside.aside)[id]`;
|
|
8336
8316
|
const selector = ':is(h1, h2, h3, h4, h5, h6, aside.aside)[id]';
|
|
8337
8317
|
function toc(source) {
|
|
8338
8318
|
const hs = [];
|
package/package.json
CHANGED
|
@@ -4,7 +4,8 @@ import { unshift, push } from 'spica/array';
|
|
|
4
4
|
|
|
5
5
|
type DelimiterOption = readonly [delimiter: string | RegExp, precedence: number];
|
|
6
6
|
|
|
7
|
-
export function some<P extends Parser<unknown>>(parser: P,
|
|
7
|
+
export function some<P extends Parser<unknown>>(parser: P, limit?: number): P;
|
|
8
|
+
export function some<P extends Parser<unknown>>(parser: P, end?: string | RegExp, delimiters?: readonly DelimiterOption[], limit?: number): P;
|
|
8
9
|
export function some<T>(parser: Parser<T>, end?: string | RegExp | number, delimiters: readonly DelimiterOption[] = [], limit = -1): Parser<T> {
|
|
9
10
|
if (typeof end === 'number') return some(parser, undefined, delimiters, end);
|
|
10
11
|
assert(parser);
|
|
@@ -15,7 +15,7 @@ function format(source: string): string {
|
|
|
15
15
|
|
|
16
16
|
function sanitize(source: string): string {
|
|
17
17
|
return source
|
|
18
|
-
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]|[\u2006\u200B-\u200F\u202A-\u202F\u2060\uFEFF]|(
|
|
18
|
+
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]|[\u2006\u200B-\u200F\u202A-\u202F\u2060\uFEFF]|(?<![\u1820\u1821])\u180E/g, UNICODE_REPLACEMENT_CHARACTER)
|
|
19
19
|
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]?|[\uDC00-\uDFFF]/g, char =>
|
|
20
20
|
char.length === 1
|
|
21
21
|
? UNICODE_REPLACEMENT_CHARACTER
|
|
@@ -16,7 +16,7 @@ export const blockquote: BlockquoteParser = lazy(() => block(rewrite(segment, un
|
|
|
16
16
|
|
|
17
17
|
const opener = /^(?=>>+(?:$|\s))/;
|
|
18
18
|
const indent = block(open(opener, some(contentline, /^>(?:$|\s)/)), false);
|
|
19
|
-
const unindent = (source: string) => source.replace(/(
|
|
19
|
+
const unindent = (source: string) => source.replace(/(?<=^|\n)>(?:[^\S\n]|(?=>*(?:$|\s)))|\n$/g, '');
|
|
20
20
|
|
|
21
21
|
const source: BlockquoteParser.SourceParser = lazy(() => fmap(
|
|
22
22
|
some(creation(1, false, union([
|
|
@@ -26,8 +26,6 @@ export const aside: ExtensionParser.AsideParser = block(validate('~~~', fmap(
|
|
|
26
26
|
},
|
|
27
27
|
}, context);
|
|
28
28
|
assert(!document.querySelector('[id]'));
|
|
29
|
-
// Bug: Firefox
|
|
30
|
-
//const heading = document.querySelector(':scope > h1:first-child');
|
|
31
29
|
const heading = 'H1 H2 H3 H4 H5 H6'.split(' ').includes(document.firstElementChild?.tagName!) && document.firstElementChild as HTMLHeadingElement;
|
|
32
30
|
if (!heading) return [html('pre', {
|
|
33
31
|
class: 'invalid',
|
|
@@ -44,8 +44,8 @@ describe('Unit: parser/block/extension/figure', () => {
|
|
|
44
44
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n\\\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext">\\</span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
46
46
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n!https://caption\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext">!<a class="url" href="https://caption" target="_blank">https://caption</a></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
47
|
-
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n- a\n~~~')), [['<figure data-type="list" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><ul><li>a</li></ul></div></figure>'], '']);
|
|
48
|
-
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n1. a\n~~~')), [['<figure data-type="list" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><ol><li>a</li></ol></div></figure>'], '']);
|
|
47
|
+
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n- a\n~~~')), [['<figure data-type="list" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><ul><li id="index:a">a</li></ul></div></figure>'], '']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n1. a\n~~~')), [['<figure data-type="list" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><ol><li id="index:a">a</li></ol></div></figure>'], '']);
|
|
49
49
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n|\n|-\n|\n~~~')), [['<figure data-type="table" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><table><thead><tr></tr></thead><tbody><tr></tr></tbody></table></div></figure>'], '']);
|
|
50
50
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n```\n\n```\n~~~')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><pre class="text"></pre></div></figure>'], '']);
|
|
51
51
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n```\n~~~\n```\n\n~~~')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><pre class="text">~~~</pre></div></figure>'], '']);
|
|
@@ -39,12 +39,12 @@ describe('Unit: parser/block/olist', () => {
|
|
|
39
39
|
// filled
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('1. \\')), [['<ol><li></li></ol>'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('1. \\\n')), [['<ol><li></li></ol>'], '']);
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('1. -')), [['<ol><li>-</li></ol>'], '']);
|
|
43
|
-
assert.deepStrictEqual(inspect(parser('1. -\n')), [['<ol><li>-</li></ol>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('1. -')), [['<ol><li id="index:-">-</li></ol>'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('1. -\n')), [['<ol><li id="index:-">-</li></ol>'], '']);
|
|
44
44
|
// pending
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('(1) ')), [['<ol data-format="paren"><li></li></ol>'], '']);
|
|
46
46
|
// filled
|
|
47
|
-
assert.deepStrictEqual(inspect(parser('(1) a')), [['<ol data-format="paren"><li>a</li></ol>'], '']);
|
|
47
|
+
assert.deepStrictEqual(inspect(parser('(1) a')), [['<ol data-format="paren"><li id="index:a">a</li></ol>'], '']);
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
it('multiple', () => {
|
|
@@ -55,8 +55,8 @@ describe('Unit: parser/block/olist', () => {
|
|
|
55
55
|
assert.deepStrictEqual(inspect(parser('0.\n0. ')), [['<ol><li></li><li></li></ol>'], '']);
|
|
56
56
|
assert.deepStrictEqual(inspect(parser('0.\n0.\n')), [['<ol><li></li><li></li></ol>'], '']);
|
|
57
57
|
// filled
|
|
58
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n0. 2')), [['<ol><li>1</li><li>2</li></ol>'], '']);
|
|
59
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n0. 2\n0. 3')), [['<ol><li>1</li><li>2</li><li>3</li></ol>'], '']);
|
|
58
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n0. 2')), [['<ol><li id="index:1">1</li><li id="index:2">2</li></ol>'], '']);
|
|
59
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n0. 2\n0. 3')), [['<ol><li id="index:1">1</li><li id="index:2">2</li><li id="index:3">3</li></ol>'], '']);
|
|
60
60
|
// pending
|
|
61
61
|
assert.deepStrictEqual(inspect(parser('(1) \n(')), [['<ol data-format="paren"><li></li><li></li></ol>'], '']);
|
|
62
62
|
assert.deepStrictEqual(inspect(parser('(1) \n(\n')), [['<ol data-format="paren"><li></li><li></li></ol>'], '']);
|
|
@@ -67,21 +67,21 @@ describe('Unit: parser/block/olist', () => {
|
|
|
67
67
|
// filled
|
|
68
68
|
assert.deepStrictEqual(inspect(parser('(1) \n(1) ')), [['<ol data-format="paren"><li></li><li></li></ol>'], '']);
|
|
69
69
|
// invalid
|
|
70
|
-
assert.deepStrictEqual(inspect(parser('0. \n0 ')), [['<ol><li></li><li><span class="invalid">0 </span></li></ol>'], '']);
|
|
70
|
+
assert.deepStrictEqual(inspect(parser('0. \n0 ')), [['<ol><li></li><li id="index:0"><span class="invalid">0 </span></li></ol>'], '']);
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
it('nest', () => {
|
|
74
74
|
assert.deepStrictEqual(inspect(parser('0.\n 0')), [['<ol><li><br><ol><li></li></ol></li></ol>'], '']);
|
|
75
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n 0')), [['<ol><li>1<ol><li></li></ol></li></ol>'], '']);
|
|
76
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n 0.')), [['<ol><li>1<ol><li></li></ol></li></ol>'], '']);
|
|
77
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n 0. ')), [['<ol><li>1<ol><li></li></ol></li></ol>'], '']);
|
|
78
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n 0.\n')), [['<ol><li>1<ol><li></li></ol></li></ol>'], '']);
|
|
79
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2')), [['<ol><li>1<ol><li>2</li></ol></li></ol>'], '']);
|
|
80
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2\n0. 3')), [['<ol><li>1<ol><li>2</li></ol></li><li>3</li></ol>'], '']);
|
|
81
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2\n 0. 3')), [['<ol><li>1<ol><li>2</li><li>3</li></ol></li></ol>'], '']);
|
|
82
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2\n 0. 3')), [['<ol><li>1<ol><li>2<ol><li>3</li></ol></li></ol></li></ol>'], '']);
|
|
83
|
-
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2\n 0. 3')), [['<ol><li>1<ol><li>2</li></ol></li><li><span class="invalid"> 0. 3</span></li></ol>'], '']);
|
|
84
|
-
assert.deepStrictEqual(inspect(parser('0. !http://host')), [['<ol><li>!<a class="url" href="http://host" target="_blank">http://host</a></li></ol>'], '']);
|
|
75
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n 0')), [['<ol><li id="index:1">1<ol><li></li></ol></li></ol>'], '']);
|
|
76
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n 0.')), [['<ol><li id="index:1">1<ol><li></li></ol></li></ol>'], '']);
|
|
77
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n 0. ')), [['<ol><li id="index:1">1<ol><li></li></ol></li></ol>'], '']);
|
|
78
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n 0.\n')), [['<ol><li id="index:1">1<ol><li></li></ol></li></ol>'], '']);
|
|
79
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2')), [['<ol><li id="index:1">1<ol><li id="index:2">2</li></ol></li></ol>'], '']);
|
|
80
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2\n0. 3')), [['<ol><li id="index:1">1<ol><li id="index:2">2</li></ol></li><li id="index:3">3</li></ol>'], '']);
|
|
81
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2\n 0. 3')), [['<ol><li id="index:1">1<ol><li id="index:2">2</li><li id="index:3">3</li></ol></li></ol>'], '']);
|
|
82
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2\n 0. 3')), [['<ol><li id="index:1">1<ol><li id="index:2">2<ol><li id="index:3">3</li></ol></li></ol></li></ol>'], '']);
|
|
83
|
+
assert.deepStrictEqual(inspect(parser('0. 1\n 0. 2\n 0. 3')), [['<ol><li id="index:1">1<ol><li id="index:2">2</li></ol></li><li id="index:0._3"><span class="invalid"> 0. 3</span></li></ol>'], '']);
|
|
84
|
+
assert.deepStrictEqual(inspect(parser('0. !http://host')), [['<ol><li id="index:!http://host">!<a class="url" href="http://host" target="_blank">http://host</a></li></ol>'], '']);
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
it('index', () => {
|
|
@@ -103,10 +103,11 @@ describe('Unit: parser/block/olist', () => {
|
|
|
103
103
|
assert.deepStrictEqual(inspect(parser('(1)-1-1 ')), [['<ol data-format="paren"><li data-marker="(1)-1-1"></li></ol>'], '']);
|
|
104
104
|
assert.deepStrictEqual(inspect(parser('(1) \n(1)-')), [['<ol data-format="paren"><li></li><li data-marker="(1)-"></li></ol>'], '']);
|
|
105
105
|
assert.deepStrictEqual(inspect(parser('(1) \n(1)-1')), [['<ol data-format="paren"><li></li><li data-marker="(1)-1"></li></ol>'], '']);
|
|
106
|
-
assert.deepStrictEqual(inspect(parser('1. \n1--')), [['<ol><li></li><li><span class="invalid">1--</span></li></ol>'], '']);
|
|
107
|
-
assert.deepStrictEqual(inspect(parser('1. \n1--. ')), [['<ol><li></li><li><span class="invalid">1--. </span></li></ol>'], '']);
|
|
108
|
-
assert.deepStrictEqual(inspect(parser('(1) \n(1)--')), [['<ol data-format="paren"><li></li><li><span class="invalid">(1)--</span></li></ol>'], '']);
|
|
109
|
-
assert.deepStrictEqual(inspect(parser('(1) \n(1)-- ')), [['<ol data-format="paren"><li></li><li><span class="invalid">(1)-- </span></li></ol>'], '']);
|
|
106
|
+
assert.deepStrictEqual(inspect(parser('1. \n1--')), [['<ol><li></li><li id="index:1--"><span class="invalid">1--</span></li></ol>'], '']);
|
|
107
|
+
assert.deepStrictEqual(inspect(parser('1. \n1--. ')), [['<ol><li></li><li id="index:1--."><span class="invalid">1--. </span></li></ol>'], '']);
|
|
108
|
+
assert.deepStrictEqual(inspect(parser('(1) \n(1)--')), [['<ol data-format="paren"><li></li><li id="index:(1)--"><span class="invalid">(1)--</span></li></ol>'], '']);
|
|
109
|
+
assert.deepStrictEqual(inspect(parser('(1) \n(1)-- ')), [['<ol data-format="paren"><li></li><li id="index:(1)--"><span class="invalid">(1)-- </span></li></ol>'], '']);
|
|
110
|
+
assert.deepStrictEqual(inspect(parser('1-1. 1')), [['<ol><li data-marker="1-1." id="index:1">1</li></ol>'], '']);
|
|
110
111
|
});
|
|
111
112
|
|
|
112
113
|
it('type', () => {
|
|
@@ -115,22 +116,23 @@ describe('Unit: parser/block/olist', () => {
|
|
|
115
116
|
assert.deepStrictEqual(inspect(parser('I. ')), [['<ol type="I" data-type="upper-roman"><li></li></ol>'], '']);
|
|
116
117
|
assert.deepStrictEqual(inspect(parser('A. ')), [['<ol type="A" data-type="upper-alpha"><li></li></ol>'], '']);
|
|
117
118
|
assert.deepStrictEqual(inspect(parser('a.\n1.\nc')), [['<ol type="a" data-type="lower-alpha"><li></li><li data-marker="1."></li><li data-marker="c."></li></ol>'], '']);
|
|
119
|
+
assert.deepStrictEqual(inspect(parser('i. 1')), [['<ol type="i" data-type="lower-roman"><li id="index:1">1</li></ol>'], '']);
|
|
118
120
|
});
|
|
119
121
|
|
|
120
122
|
it('checkbox', () => {
|
|
121
123
|
assert.deepStrictEqual(inspect(parser('1. [ ]')), [['<ol class="checklist"><li><span class="checkbox">☐</span></li></ol>'], '']);
|
|
122
124
|
assert.deepStrictEqual(inspect(parser('1. [x]')), [['<ol class="checklist"><li><span class="checkbox">☑</span></li></ol>'], '']);
|
|
123
125
|
assert.deepStrictEqual(inspect(parser('1. [X]')), [['<ol class="checklist"><li><span class="checkbox">☑</span></li></ol>'], '']);
|
|
124
|
-
assert.deepStrictEqual(inspect(parser('1. [X] 1')), [['<ol class="checklist"><li><span class="checkbox">☑</span>1</li></ol>'], '']);
|
|
126
|
+
assert.deepStrictEqual(inspect(parser('1. [X] 1')), [['<ol class="checklist"><li id="index:1"><span class="checkbox">☑</span>1</li></ol>'], '']);
|
|
125
127
|
});
|
|
126
128
|
|
|
127
129
|
it('indexer', () => {
|
|
128
|
-
assert.deepStrictEqual(inspect(parser('1. [#a]')), [['<ol><li><a class="index" href="#index:a">a</a></li></ol>'], '']);
|
|
129
|
-
assert.deepStrictEqual(inspect(parser('1. a [#]')), [['<ol><li
|
|
130
|
+
assert.deepStrictEqual(inspect(parser('1. [#a]')), [['<ol><li id="index:a"><a class="index" href="#index:a">a</a></li></ol>'], '']);
|
|
131
|
+
assert.deepStrictEqual(inspect(parser('1. a [#]')), [['<ol><li>a<span class="indexer" data-index=""></span></li></ol>'], '']);
|
|
130
132
|
assert.deepStrictEqual(inspect(parser('1. a [#b]')), [['<ol><li id="index:b">a<span class="indexer" data-index="b"></span></li></ol>'], '']);
|
|
131
|
-
assert.deepStrictEqual(inspect(parser('1. [ ] [#a]')), [['<ol class="checklist"><li><span class="checkbox">☐</span><a class="index" href="#index:a">a</a></li></ol>'], '']);
|
|
133
|
+
assert.deepStrictEqual(inspect(parser('1. [ ] [#a]')), [['<ol class="checklist"><li id="index:a"><span class="checkbox">☐</span><a class="index" href="#index:a">a</a></li></ol>'], '']);
|
|
132
134
|
assert.deepStrictEqual(inspect(parser('1. [ ] a [#b]')), [['<ol class="checklist"><li id="index:b"><span class="checkbox">☐</span>a<span class="indexer" data-index="b"></span></li></ol>'], '']);
|
|
133
|
-
assert.deepStrictEqual(inspect(parser('1. a [#]\n 1. c [#d]')), [['<ol><li
|
|
135
|
+
assert.deepStrictEqual(inspect(parser('1. a [#]\n 1. c [#d]')), [['<ol><li>a<span class="indexer" data-index=""></span><ol><li id="index:d">c<span class="indexer" data-index="d"></span></li></ol></li></ol>'], '']);
|
|
134
136
|
assert.deepStrictEqual(inspect(parser('1. a [#b]\n 1. c [#d]')), [['<ol><li id="index:b">a<span class="indexer" data-index="b"></span><ol><li id="index:d">c<span class="indexer" data-index="d"></span></li></ol></li></ol>'], '']);
|
|
135
137
|
});
|
|
136
138
|
|
|
@@ -17,7 +17,7 @@ export const sidefence: SidefenceParser = lazy(() => block(fmap(focus(
|
|
|
17
17
|
])));
|
|
18
18
|
|
|
19
19
|
const opener = /^(?=\|\|+(?:$|\s))/;
|
|
20
|
-
const unindent = (source: string) => source.replace(/(
|
|
20
|
+
const unindent = (source: string) => source.replace(/(?<=^|\n)\|(?:[^\S\n]|(?=\|*(?:$|\s)))|\n$/g, '');
|
|
21
21
|
|
|
22
22
|
const source: SidefenceParser.SourceParser = lazy(() => fmap(
|
|
23
23
|
some(creation(1, false, union([
|
|
@@ -28,51 +28,51 @@ describe('Unit: parser/block/ulist', () => {
|
|
|
28
28
|
// filled
|
|
29
29
|
assert.deepStrictEqual(inspect(parser('- \\')), [['<ul><li></li></ul>'], '']);
|
|
30
30
|
assert.deepStrictEqual(inspect(parser('- \\\n')), [['<ul><li></li></ul>'], '']);
|
|
31
|
-
assert.deepStrictEqual(inspect(parser('- -')), [['<ul><li>-</li></ul>'], '']);
|
|
32
|
-
assert.deepStrictEqual(inspect(parser('- -\n')), [['<ul><li>-</li></ul>'], '']);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser('- -')), [['<ul><li id="index:-">-</li></ul>'], '']);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser('- -\n')), [['<ul><li id="index:-">-</li></ul>'], '']);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
it('multiple', () => {
|
|
36
36
|
// pending
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('-\n-')), [['<ul><li></li><li></li></ul>'], '']);
|
|
38
38
|
// filled
|
|
39
|
-
assert.deepStrictEqual(inspect(parser('- 1\n- 2')), [['<ul><li>1</li><li>2</li></ul>'], '']);
|
|
40
|
-
assert.deepStrictEqual(inspect(parser('- 1\n- 2\n- 3')), [['<ul><li>1</li><li>2</li><li>3</li></ul>'], '']);
|
|
39
|
+
assert.deepStrictEqual(inspect(parser('- 1\n- 2')), [['<ul><li id="index:1">1</li><li id="index:2">2</li></ul>'], '']);
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('- 1\n- 2\n- 3')), [['<ul><li id="index:1">1</li><li id="index:2">2</li><li id="index:3">3</li></ul>'], '']);
|
|
41
41
|
// invalid
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('-\n+')), [['<ul><li></li><li><span class="invalid">+</span></li></ul>'], '']);
|
|
43
|
-
assert.deepStrictEqual(inspect(parser('-\n0')), [['<ul><li></li><li><span class="invalid">0</span></li></ul>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('-\n+')), [['<ul><li></li><li id="index:+"><span class="invalid">+</span></li></ul>'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('-\n0')), [['<ul><li></li><li id="index:0"><span class="invalid">0</span></li></ul>'], '']);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
it('nest', () => {
|
|
47
47
|
assert.deepStrictEqual(inspect(parser('-\n -')), [['<ul><li><br><ul><li></li></ul></li></ul>'], '']);
|
|
48
|
-
assert.deepStrictEqual(inspect(parser('- 1\n - 2')), [['<ul><li>1<ul><li>2</li></ul></li></ul>'], '']);
|
|
49
|
-
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n- 3')), [['<ul><li>1<ul><li>2</li></ul></li><li>3</li></ul>'], '']);
|
|
50
|
-
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n - 3')), [['<ul><li>1<ul><li>2</li><li>3</li></ul></li></ul>'], '']);
|
|
51
|
-
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n - 3')), [['<ul><li>1<ul><li>2<ul><li>3</li></ul></li></ul></li></ul>'], '']);
|
|
52
|
-
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n - 3')), [['<ul><li>1<ul><li>2</li></ul></li><li><span class="invalid"> - 3</span></li></ul>'], '']);
|
|
53
|
-
assert.deepStrictEqual(inspect(parser('-\n -\n +\n -\n +\n+')), [['<ul><li><br><ul><li></li><li><span class="invalid">+</span></li><li></li><li><span class="invalid">+</span></li></ul></li><li><span class="invalid">+</span></li></ul>'], '']);
|
|
54
|
-
assert.deepStrictEqual(inspect(parser('- 1\n + 2')), [['<ul><li>1<ul class="invalid"><li>2</li></ul></li></ul>'], '']);
|
|
55
|
-
assert.deepStrictEqual(inspect(parser('- 1\n 0')), [['<ul><li>1<ol><li></li></ol></li></ul>'], '']);
|
|
56
|
-
assert.deepStrictEqual(inspect(parser('- 1\n 0.')), [['<ul><li>1<ol><li></li></ol></li></ul>'], '']);
|
|
57
|
-
assert.deepStrictEqual(inspect(parser('- 1\n 0. ')), [['<ul><li>1<ol><li></li></ol></li></ul>'], '']);
|
|
58
|
-
assert.deepStrictEqual(inspect(parser('- 1\n 0. 2')), [['<ul><li>1<ol><li>2</li></ol></li></ul>'], '']);
|
|
59
|
-
assert.deepStrictEqual(inspect(parser('- !http://host')), [['<ul><li>!<a class="url" href="http://host" target="_blank">http://host</a></li></ul>'], '']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('- 1\n - 2')), [['<ul><li id="index:1">1<ul><li id="index:2">2</li></ul></li></ul>'], '']);
|
|
49
|
+
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n- 3')), [['<ul><li id="index:1">1<ul><li id="index:2">2</li></ul></li><li id="index:3">3</li></ul>'], '']);
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n - 3')), [['<ul><li id="index:1">1<ul><li id="index:2">2</li><li id="index:3">3</li></ul></li></ul>'], '']);
|
|
51
|
+
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n - 3')), [['<ul><li id="index:1">1<ul><li id="index:2">2<ul><li id="index:3">3</li></ul></li></ul></li></ul>'], '']);
|
|
52
|
+
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n - 3')), [['<ul><li id="index:1">1<ul><li id="index:2">2</li></ul></li><li id="index:-_3"><span class="invalid"> - 3</span></li></ul>'], '']);
|
|
53
|
+
assert.deepStrictEqual(inspect(parser('-\n -\n +\n -\n +\n+')), [['<ul><li><br><ul><li></li><li id="index:+"><span class="invalid">+</span></li><li></li><li id="index:+"><span class="invalid">+</span></li></ul></li><li id="index:+"><span class="invalid">+</span></li></ul>'], '']);
|
|
54
|
+
assert.deepStrictEqual(inspect(parser('- 1\n + 2')), [['<ul><li id="index:1">1<ul class="invalid"><li>2</li></ul></li></ul>'], '']);
|
|
55
|
+
assert.deepStrictEqual(inspect(parser('- 1\n 0')), [['<ul><li id="index:1">1<ol><li></li></ol></li></ul>'], '']);
|
|
56
|
+
assert.deepStrictEqual(inspect(parser('- 1\n 0.')), [['<ul><li id="index:1">1<ol><li></li></ol></li></ul>'], '']);
|
|
57
|
+
assert.deepStrictEqual(inspect(parser('- 1\n 0. ')), [['<ul><li id="index:1">1<ol><li></li></ol></li></ul>'], '']);
|
|
58
|
+
assert.deepStrictEqual(inspect(parser('- 1\n 0. 2')), [['<ul><li id="index:1">1<ol><li id="index:2">2</li></ol></li></ul>'], '']);
|
|
59
|
+
assert.deepStrictEqual(inspect(parser('- !http://host')), [['<ul><li id="index:!http://host">!<a class="url" href="http://host" target="_blank">http://host</a></li></ul>'], '']);
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
it('checkbox', () => {
|
|
63
63
|
assert.deepStrictEqual(inspect(parser('- [ ]')), [['<ul class="checklist"><li><span class="checkbox">☐</span></li></ul>'], '']);
|
|
64
64
|
assert.deepStrictEqual(inspect(parser('- [x]')), [['<ul class="checklist"><li><span class="checkbox">☑</span></li></ul>'], '']);
|
|
65
65
|
assert.deepStrictEqual(inspect(parser('- [X]')), [['<ul class="checklist"><li><span class="checkbox">☑</span></li></ul>'], '']);
|
|
66
|
-
assert.deepStrictEqual(inspect(parser('- [X] 1')), [['<ul class="checklist"><li><span class="checkbox">☑</span>1</li></ul>'], '']);
|
|
66
|
+
assert.deepStrictEqual(inspect(parser('- [X] 1')), [['<ul class="checklist"><li id="index:1"><span class="checkbox">☑</span>1</li></ul>'], '']);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
it('indexer', () => {
|
|
70
|
-
assert.deepStrictEqual(inspect(parser('- [#a]')), [['<ul><li><a class="index" href="#index:a">a</a></li></ul>'], '']);
|
|
71
|
-
assert.deepStrictEqual(inspect(parser('- a [#]')), [['<ul><li
|
|
70
|
+
assert.deepStrictEqual(inspect(parser('- [#a]')), [['<ul><li id="index:a"><a class="index" href="#index:a">a</a></li></ul>'], '']);
|
|
71
|
+
assert.deepStrictEqual(inspect(parser('- a [#]')), [['<ul><li>a<span class="indexer" data-index=""></span></li></ul>'], '']);
|
|
72
72
|
assert.deepStrictEqual(inspect(parser('- a [#b]')), [['<ul><li id="index:b">a<span class="indexer" data-index="b"></span></li></ul>'], '']);
|
|
73
|
-
assert.deepStrictEqual(inspect(parser('- [ ] [#a]')), [['<ul class="checklist"><li><span class="checkbox">☐</span><a class="index" href="#index:a">a</a></li></ul>'], '']);
|
|
73
|
+
assert.deepStrictEqual(inspect(parser('- [ ] [#a]')), [['<ul class="checklist"><li id="index:a"><span class="checkbox">☐</span><a class="index" href="#index:a">a</a></li></ul>'], '']);
|
|
74
74
|
assert.deepStrictEqual(inspect(parser('- [ ] a [#b]')), [['<ul class="checklist"><li id="index:b"><span class="checkbox">☐</span>a<span class="indexer" data-index="b"></span></li></ul>'], '']);
|
|
75
|
-
assert.deepStrictEqual(inspect(parser('- a [#]\n - c [#d]')), [['<ul><li
|
|
75
|
+
assert.deepStrictEqual(inspect(parser('- a [#]\n - c [#d]')), [['<ul><li>a<span class="indexer" data-index=""></span><ul><li id="index:d">c<span class="indexer" data-index="d"></span></li></ul></li></ul>'], '']);
|
|
76
76
|
assert.deepStrictEqual(inspect(parser('- a [#b]\n - c [#d]')), [['<ul><li id="index:b">a<span class="indexer" data-index="b"></span><ul><li id="index:d">c<span class="indexer" data-index="d"></span></li></ul></li></ul>'], '']);
|
|
77
77
|
});
|
|
78
78
|
|
|
@@ -30,31 +30,29 @@ export function text(source: HTMLElement | DocumentFragment, optional = false):
|
|
|
30
30
|
assert(source instanceof DocumentFragment || !source.matches('.indexer'));
|
|
31
31
|
assert(source.querySelectorAll(':scope > .indexer').length <= 1);
|
|
32
32
|
const indexer = source.querySelector(':scope > .indexer');
|
|
33
|
-
if (!indexer && optional) return '';
|
|
34
33
|
const index = indexer?.getAttribute('data-index');
|
|
35
34
|
if (index) return index;
|
|
36
|
-
|
|
35
|
+
if (index === '' && optional) return '';
|
|
36
|
+
assert(!navigator.userAgent.includes('Chrome') || !source.querySelector('br:not(:has(+ :is(ul, ol)))'));
|
|
37
37
|
const target = source.cloneNode(true) as typeof source;
|
|
38
38
|
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .comment, rt, rp, br, .annotation, .reference, .checkbox, ul, ol'),
|
|
39
39
|
len = es.length, i = 0; i < len; ++i) {
|
|
40
40
|
const el = es[i];
|
|
41
41
|
switch (el.tagName) {
|
|
42
42
|
case 'CODE':
|
|
43
|
-
|
|
43
|
+
el.replaceWith(el.getAttribute('data-src')!);
|
|
44
44
|
continue;
|
|
45
45
|
case 'RT':
|
|
46
46
|
case 'RP':
|
|
47
|
+
case 'BR':
|
|
47
48
|
case 'UL':
|
|
48
49
|
case 'OL':
|
|
49
50
|
el.remove();
|
|
50
51
|
continue;
|
|
51
|
-
case 'BR':
|
|
52
|
-
el.replaceWith('\n');
|
|
53
|
-
continue;
|
|
54
52
|
}
|
|
55
53
|
switch (el.className) {
|
|
56
54
|
case 'math':
|
|
57
|
-
|
|
55
|
+
el.replaceWith(el.getAttribute('data-src')!);
|
|
58
56
|
continue;
|
|
59
57
|
case 'comment':
|
|
60
58
|
case 'checkbox':
|
|
@@ -20,33 +20,33 @@ describe('Unit: parser/inline/link', () => {
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
it('fishing', () => {
|
|
23
|
-
assert.deepStrictEqual(inspect(parser('[http://host]{http://evil}')),
|
|
24
|
-
assert.deepStrictEqual(inspect(parser('[\\http://host]{http://evil}')),
|
|
25
|
-
assert.deepStrictEqual(inspect(parser('[https://host]{http://host}')),
|
|
26
|
-
assert.deepStrictEqual(inspect(parser('[[]{http://host}.com]{http://host}')),
|
|
27
|
-
assert.deepStrictEqual(inspect(parser('[[]{http://host/a}b]{http://host/ab}')),
|
|
23
|
+
assert.deepStrictEqual(inspect(parser('[http://host]{http://evil}')), [['<a class="invalid">http://host</a>'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('[\\http://host]{http://evil}')), [['<a class="invalid">http://host</a>'], '']);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser('[https://host]{http://host}')), [['<a class="invalid">https://host</a>'], '']);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser('[[]{http://host}.com]{http://host}')), [['<a class="invalid">[]{http://host}.com</a>'], '']);
|
|
27
|
+
assert.deepStrictEqual(inspect(parser('[[]{http://host/a}b]{http://host/ab}')), [['<a class="invalid">[]{http://host/a}b</a>'], '']);
|
|
28
28
|
assert.deepStrictEqual(inspect(parser('{http%73://host}')), [['<a class="url" href="http%73://host">http%73://host</a>'], '']);
|
|
29
29
|
assert.deepStrictEqual(inspect(parser('{http://a%C3%A1}')), [['<a class="url" href="http://a%C3%A1" target="_blank">http://a%C3%A1</a>'], '']);
|
|
30
|
-
assert.deepStrictEqual(inspect(parser('[http://á]{http://evil}')),
|
|
31
|
-
assert.deepStrictEqual(inspect(parser('[xxx://á]{http://evil}')),
|
|
32
|
-
assert.deepStrictEqual(inspect(parser('[mailto:á]{http://evil}')),
|
|
33
|
-
assert.deepStrictEqual(inspect(parser('[file:///]{http://evil}')),
|
|
34
|
-
assert.deepStrictEqual(inspect(parser('[.http://á]{http://evil}')),
|
|
30
|
+
assert.deepStrictEqual(inspect(parser('[http://á]{http://evil}')), [['<a class="invalid">http://á</a>'], '']);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser('[xxx://á]{http://evil}')), [['<a class="invalid">xxx://á</a>'], '']);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser('[mailto:á]{http://evil}')), [['<a class="invalid">mailto:á</a>'], '']);
|
|
33
|
+
assert.deepStrictEqual(inspect(parser('[file:///]{http://evil}')), [['<a class="invalid">file:///</a>'], '']);
|
|
34
|
+
assert.deepStrictEqual(inspect(parser('[.http://á]{http://evil}')), [['<a class="invalid">.http://á</a>'], '']);
|
|
35
35
|
assert.deepStrictEqual(inspect(parser('[0987654321]{tel:1234567890}')), [['<a class="invalid">0987654321</a>'], '']);
|
|
36
36
|
assert.deepStrictEqual(inspect(parser('[1234567890-]{tel:1234567890}')), [['<a class="invalid">1234567890-</a>'], '']);
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('[-1234567890]{tel:1234567890}')), [['<a class="invalid">-1234567890</a>'], '']);
|
|
38
38
|
assert.deepStrictEqual(inspect(parser('[123456789a]{tel:1234567890}')), [['<a class="invalid">123456789a</a>'], '']);
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('[1234567890]{tel:ttel:1234567890}')), [['<a class="invalid">1234567890</a>'], '']);
|
|
40
|
-
//assert.deepStrictEqual(inspect(parser('[#a]{b}')),
|
|
41
|
-
//assert.deepStrictEqual(inspect(parser('[\\#a]{b}')),
|
|
42
|
-
//assert.deepStrictEqual(inspect(parser('[c #a]{b}')),
|
|
43
|
-
//assert.deepStrictEqual(inspect(parser('[c \\#a]{b}')),
|
|
44
|
-
//assert.deepStrictEqual(inspect(parser('[]{#a}')), [['<a class="
|
|
45
|
-
//assert.deepStrictEqual(inspect(parser('[@a]{b}')),
|
|
46
|
-
//assert.deepStrictEqual(inspect(parser('[\\@a]{b}')),
|
|
47
|
-
//assert.deepStrictEqual(inspect(parser('[c @a]{b}')),
|
|
48
|
-
//assert.deepStrictEqual(inspect(parser('[c \\@a]{b}')),
|
|
49
|
-
//assert.deepStrictEqual(inspect(parser('[]{@a}')), [['<a class="
|
|
40
|
+
//assert.deepStrictEqual(inspect(parser('[#a]{b}')), [['<a class="link" href="b">#a</a>'], '']);
|
|
41
|
+
//assert.deepStrictEqual(inspect(parser('[\\#a]{b}')), [['<a class="link" href="b">#a</a>'], '']);
|
|
42
|
+
//assert.deepStrictEqual(inspect(parser('[c #a]{b}')), [['<a class="link" href="b">c #a</a>'], '']);
|
|
43
|
+
//assert.deepStrictEqual(inspect(parser('[c \\#a]{b}')), [['<a class="link" href="b">c #a</a>'], '']);
|
|
44
|
+
//assert.deepStrictEqual(inspect(parser('[]{#a}')), [['<a class="url" href="#a">#a</a>'], '']);
|
|
45
|
+
//assert.deepStrictEqual(inspect(parser('[@a]{b}')), [['<a class="link" href="b">@a</a>'], '']);
|
|
46
|
+
//assert.deepStrictEqual(inspect(parser('[\\@a]{b}')), [['<a class="link" href="b">@a</a>'], '']);
|
|
47
|
+
//assert.deepStrictEqual(inspect(parser('[c @a]{b}')), [['<a class="link" href="b">c @a</a>'], '']);
|
|
48
|
+
//assert.deepStrictEqual(inspect(parser('[c \\@a]{b}')), [['<a class="link" href="b">c @a</a>'], '']);
|
|
49
|
+
//assert.deepStrictEqual(inspect(parser('[]{@a}')), [['<a class="url" href="@a">@a</a>'], '']);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
it('invalid', () => {
|
|
@@ -79,7 +79,7 @@ describe('Unit: parser/inline/link', () => {
|
|
|
79
79
|
assert.deepStrictEqual(inspect(parser('[a\\\nb]{b}')), undefined);
|
|
80
80
|
assert.deepStrictEqual(inspect(parser('[<wbr>]{b}')), undefined);
|
|
81
81
|
assert.deepStrictEqual(inspect(parser('[*a\nb*]{/}')), undefined);
|
|
82
|
-
assert.deepStrictEqual(inspect(parser('[http://host]{http://host}')),
|
|
82
|
+
assert.deepStrictEqual(inspect(parser('[http://host]{http://host}')), [['<a class="invalid">http://host</a>'], '']);
|
|
83
83
|
assert.deepStrictEqual(inspect(parser('[]{ttp://host}')), [['<a class="invalid">ttp://host</a>'], '']);
|
|
84
84
|
//assert.deepStrictEqual(inspect(parser('[]{http://[::ffff:0:0%1]}')), [['<a class="invalid">http://[::ffff:0:0%1]</a>'], '']);
|
|
85
85
|
//assert.deepStrictEqual(inspect(parser('[]{http://[::ffff:0:0/96]}')), [['<a class="invalid">http://[::ffff:0:0/96]</a>'], '']);
|
|
@@ -171,7 +171,11 @@ describe('Unit: parser/inline/link', () => {
|
|
|
171
171
|
assert.deepStrictEqual(inspect(parser('[((a))]{b}')), [['<a class="link" href="b"><span class="paren">((a))</span></a>'], '']);
|
|
172
172
|
assert.deepStrictEqual(inspect(parser('[[[a]]]{b}')), [['<a class="link" href="b">[[a]]</a>'], '']);
|
|
173
173
|
assert.deepStrictEqual(inspect(parser('[!http://host]{/}')), [['<a class="link" href="/" target="_blank"><img class="media" data-src="http://host" alt=""></a>'], '']);
|
|
174
|
-
assert.deepStrictEqual(inspect(parser('[
|
|
174
|
+
assert.deepStrictEqual(inspect(parser('[#a]{b}')), [['<a class="link" href="b">#a</a>'], '']);
|
|
175
|
+
assert.deepStrictEqual(inspect(parser('[@a]{b}')), [['<a class="link" href="b">@a</a>'], '']);
|
|
176
|
+
assert.deepStrictEqual(inspect(parser('[@a@b]{c}')), [['<a class="link" href="c">@a@b</a>'], '']);
|
|
177
|
+
assert.deepStrictEqual(inspect(parser('[a@b]{c}')), [['<a class="link" href="c">a@b</a>'], '']);
|
|
178
|
+
assert.deepStrictEqual(inspect(parser('[*a*]{b}')), [['<a class="link" href="b"><strong>a</strong></a>'], '']);
|
|
175
179
|
});
|
|
176
180
|
|
|
177
181
|
it('external', () => {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../../markdown';
|
|
2
2
|
import { LinkParser } from '../inline';
|
|
3
|
-
import { Result
|
|
4
|
-
import { union, inits, tails, sequence, some, constraint, syntax, creation, precedence,
|
|
3
|
+
import { Result } from '../../combinator/data/parser';
|
|
4
|
+
import { union, inits, tails, sequence, some, constraint, syntax, creation, precedence, validate, surround, open, dup, reverse, lazy, fmap, bind } from '../../combinator';
|
|
5
5
|
import { inline, media, shortmedia } from '../inline';
|
|
6
6
|
import { attributes } from './html';
|
|
7
|
-
import { autolink as autolink_ } from '../autolink';
|
|
8
7
|
import { unescsource, str } from '../source';
|
|
9
8
|
import { Syntax, State } from '../context';
|
|
10
9
|
import { trimNode } from '../visibility';
|
|
@@ -74,8 +73,6 @@ export const option: LinkParser.ParameterParser.OptionParser = union([
|
|
|
74
73
|
fmap(str(/^[^\S\n]+[^\s{}]+/), opt => [` \\${opt.slice(1)}`]),
|
|
75
74
|
]);
|
|
76
75
|
|
|
77
|
-
const autolink = state(State.autolink, false, state(State.shortcut, autolink_));
|
|
78
|
-
|
|
79
76
|
function parse(
|
|
80
77
|
content: (string | HTMLElement)[],
|
|
81
78
|
params: string[],
|
|
@@ -85,13 +82,6 @@ function parse(
|
|
|
85
82
|
assert(params.length > 0);
|
|
86
83
|
assert(params.every(p => typeof p === 'string'));
|
|
87
84
|
if (content.length !== 0 && trimNode(content).length === 0) return;
|
|
88
|
-
content = defrag(content);
|
|
89
|
-
for (let source = stringify(content); source;) {
|
|
90
|
-
if (/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i.test(source)) return;
|
|
91
|
-
const result = autolink({ source, context });
|
|
92
|
-
if (typeof eval(result, [])[0] === 'object') return;
|
|
93
|
-
source = exec(result, '');
|
|
94
|
-
}
|
|
95
85
|
const INSECURE_URI = params.shift()!;
|
|
96
86
|
assert(INSECURE_URI === INSECURE_URI.trim());
|
|
97
87
|
assert(!INSECURE_URI.match(/\s/));
|
|
@@ -100,7 +90,7 @@ function parse(
|
|
|
100
90
|
context.host?.href || location.href);
|
|
101
91
|
const el = elem(
|
|
102
92
|
INSECURE_URI,
|
|
103
|
-
content,
|
|
93
|
+
defrag(content),
|
|
104
94
|
uri,
|
|
105
95
|
context.host?.origin || location.origin);
|
|
106
96
|
if (el.className === 'invalid') return [[el], rest];
|
|
@@ -120,6 +110,10 @@ function elem(
|
|
|
120
110
|
case 'https:':
|
|
121
111
|
assert(uri.host);
|
|
122
112
|
switch (true) {
|
|
113
|
+
case /[a-z][0-9]*:\/{0,2}\S/i.test(stringify(content)):
|
|
114
|
+
type = 'content';
|
|
115
|
+
message = 'URI must not be contained';
|
|
116
|
+
break;
|
|
123
117
|
case INSECURE_URI.slice(0, 2) === '^/'
|
|
124
118
|
&& /\/\.\.?(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/))):
|
|
125
119
|
type = 'argument';
|
|
@@ -165,6 +159,7 @@ function elem(
|
|
|
165
159
|
type = 'content';
|
|
166
160
|
message = 'Invalid content';
|
|
167
161
|
}
|
|
162
|
+
break;
|
|
168
163
|
}
|
|
169
164
|
return html('a',
|
|
170
165
|
{
|
|
@@ -205,7 +200,7 @@ function decode(uri: string): string {
|
|
|
205
200
|
const origin = uri.match(/^[a-z](?:[-.](?=\w)|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i)?.[0] ?? '';
|
|
206
201
|
try {
|
|
207
202
|
let path = decodeURI(uri.slice(origin.length));
|
|
208
|
-
if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])
|
|
203
|
+
if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])*:\/{0,2}\S/i.test(path)) {
|
|
209
204
|
path = uri.slice(origin.length);
|
|
210
205
|
}
|
|
211
206
|
uri = origin + path;
|
|
@@ -29,6 +29,7 @@ describe('Unit: parser/inline', () => {
|
|
|
29
29
|
assert.deepStrictEqual(inspect(parser('*[*]')), [['*', '[', '*', ']'], '']);
|
|
30
30
|
assert.deepStrictEqual(inspect(parser('*<*>')), [['<strong><</strong>', '>'], '']);
|
|
31
31
|
assert.deepStrictEqual(inspect(parser('*a((b))*')), [['<strong>a<sup class="annotation"><span>b</span></sup></strong>'], '']);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser('++\na\n++\n~~\nb\n~~\nc')), [['<ins><br>a</ins>', '<br>', '<del><br>b</del>', '<br>', 'c'], '']);
|
|
32
33
|
assert.deepStrictEqual(inspect(parser('``a`')), [['``', 'a', '`'], '']);
|
|
33
34
|
assert.deepStrictEqual(inspect(parser('[@a]')), [['[', '<a class="account" href="/@a">@a</a>', ']'], '']);
|
|
34
35
|
assert.deepStrictEqual(inspect(parser('[#1][#2]')), [['<a class="index" href="#index:1">1</a>', '<a class="index" href="#index:2">2</a>'], '']);
|
|
@@ -46,8 +47,8 @@ describe('Unit: parser/inline', () => {
|
|
|
46
47
|
assert.deepStrictEqual(inspect(parser('[[#-1]a](b)')), [['[', '<a class="index" href="#index:-1">-1</a>', 'a', ']', '(', 'b', ')'], '']);
|
|
47
48
|
assert.deepStrictEqual(inspect(parser('[#a]{b}')), [['<a class="index" href="#index:a">a</a>', '<a class="url" href="b">b</a>'], '']);
|
|
48
49
|
assert.deepStrictEqual(inspect(parser('[@a]{b}')), [['<a class="link" href="b">@a</a>'], '']);
|
|
49
|
-
assert.deepStrictEqual(inspect(parser('[http://host]{http://evil}')), [['
|
|
50
|
-
assert.deepStrictEqual(inspect(parser('[http://host]{http://host}')), [['
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('[http://host]{http://evil}')), [['<a class="invalid">http://host</a>'], '']);
|
|
51
|
+
assert.deepStrictEqual(inspect(parser('[http://host]{http://host}')), [['<a class="invalid">http://host</a>'], '']);
|
|
51
52
|
assert.deepStrictEqual(inspect(parser('[]{{a}}')), [['[', ']', '<span class="template">{{a}}</span>'], '']);
|
|
52
53
|
assert.deepStrictEqual(inspect(parser('![]{{a}}')), [['!', '[', ']', '<span class="template">{{a}}</span>'], '']);
|
|
53
54
|
assert.deepStrictEqual(inspect(parser('[\n]{a}')), [['[', '<br>', ']', '<a class="url" href="a">a</a>'], '']);
|
|
@@ -18,8 +18,6 @@ export function* figure(
|
|
|
18
18
|
let base = '0';
|
|
19
19
|
let bases: readonly string[] = base.split('.');
|
|
20
20
|
let index: readonly string[] = bases;
|
|
21
|
-
// Bug: Firefox
|
|
22
|
-
//for (let defs = target.querySelectorAll(':scope > figure[data-label], :scope > h1, :scope > h2'), len = defs.length, i = 0; i < len; ++i) {
|
|
23
21
|
for (
|
|
24
22
|
let defs = target.querySelectorAll('figure[data-label], h1, h2'),
|
|
25
23
|
len = defs.length, i = 0; i < len; ++i) {
|
|
@@ -8,8 +8,6 @@ export function* footnote(
|
|
|
8
8
|
opts: { readonly id?: string; } = {},
|
|
9
9
|
bottom: Node | null = null,
|
|
10
10
|
): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
|
|
11
|
-
// Bug: Firefox
|
|
12
|
-
//target.querySelectorAll(`:scope > .annotations`).forEach(el => el.remove());
|
|
13
11
|
for (let es = target.querySelectorAll(`.annotations`),
|
|
14
12
|
len = es.length, i = 0; i < len; ++i) {
|
|
15
13
|
const el = es[i];
|
|
@@ -40,8 +38,6 @@ function build(
|
|
|
40
38
|
const defs = new Map<string, HTMLLIElement>();
|
|
41
39
|
const buffer = new MultiQueue<string, HTMLElement>();
|
|
42
40
|
const titles = new Map<string, string>();
|
|
43
|
-
// Bug: Firefox
|
|
44
|
-
//const splitters = push([], target.querySelectorAll(`:scope > :is(${splitter ?? '_'})`));
|
|
45
41
|
const splitters: Element[] = [];
|
|
46
42
|
for (let es = target.querySelectorAll(splitter ?? '_'),
|
|
47
43
|
len = es.length, i = 0; i < len; ++i) {
|
package/src/util/toc.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { push } from 'spica/array';
|
|
2
2
|
import { html } from 'typed-dom/dom';
|
|
3
3
|
|
|
4
|
-
// Bug: Firefox
|
|
5
|
-
//const selector = `:scope > :is(h1, h2, h3, h4, h5, h6, aside.aside)[id]`;
|
|
6
4
|
const selector = ':is(h1, h2, h3, h4, h5, h6, aside.aside)[id]';
|
|
7
5
|
|
|
8
6
|
export function toc(source: DocumentFragment | HTMLElement | ShadowRoot): HTMLUListElement {
|