securemark 0.223.0 → 0.224.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 +64 -63
- package/package-lock.json +48 -56
- package/package.json +1 -1
- package/src/parser/api/parse.test.ts +0 -8
- package/src/parser/inline/annotation.ts +3 -3
- package/src/parser/inline/html.ts +6 -6
- package/src/parser/inline/link.test.ts +22 -3
- package/src/parser/inline/link.ts +22 -24
- package/src/parser/inline/media.test.ts +2 -1
- package/src/parser/inline/media.ts +30 -18
- package/src/parser/inline/reference.ts +5 -5
- package/src/parser/util.ts +8 -16
- package/src/renderer/render.ts +1 -2
package/CHANGELOG.md
CHANGED
package/dist/securemark.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.
|
|
1
|
+
/*! securemark v0.224.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) {
|
|
@@ -6625,7 +6625,7 @@ require = function () {
|
|
|
6625
6625
|
exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('((', '))', '\n', (0, combinator_1.fmap)((0, combinator_1.surround)('((', (0, combinator_1.guard)(context => {
|
|
6626
6626
|
var _a, _b, _c;
|
|
6627
6627
|
return (_c = (_b = (_a = context.syntax) === null || _a === void 0 ? void 0 : _a.inline) === null || _b === void 0 ? void 0 : _b.annotation) !== null && _c !== void 0 ? _c : true;
|
|
6628
|
-
}, (0, util_1.startLoose)((0,
|
|
6628
|
+
}, (0, util_1.startLoose)((0, combinator_1.context)({
|
|
6629
6629
|
syntax: {
|
|
6630
6630
|
inline: {
|
|
6631
6631
|
annotation: false,
|
|
@@ -6633,7 +6633,7 @@ require = function () {
|
|
|
6633
6633
|
}
|
|
6634
6634
|
},
|
|
6635
6635
|
state: global_1.undefined
|
|
6636
|
-
}, (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, ')', /^\\?\n/)]))))), '))'), ns => [(0, typed_dom_1.html)('sup', { class: 'annotation' }, (0, util_1.trimNode)((0, typed_dom_1.defrag)(ns)))]))));
|
|
6636
|
+
}, (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, ')', /^\\?\n/)])), '))')), '))'), ns => [(0, typed_dom_1.html)('sup', { class: 'annotation' }, (0, util_1.trimNode)((0, typed_dom_1.defrag)(ns)))]))));
|
|
6637
6637
|
},
|
|
6638
6638
|
{
|
|
6639
6639
|
'../../combinator': 30,
|
|
@@ -7485,7 +7485,7 @@ require = function () {
|
|
|
7485
7485
|
[(0, typed_dom_1.html)(tag, attributes('html', [], attrspec[tag], as))],
|
|
7486
7486
|
rest
|
|
7487
7487
|
]), ([, tag]) => tag)),
|
|
7488
|
-
(0, combinator_1.match)(/^(?=<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${ tag }`, `</${ tag }>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${ tag }`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)('>'), true), (0, util_1.startLoose)((0,
|
|
7488
|
+
(0, combinator_1.match)(/^(?=<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${ tag }`, `</${ tag }>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${ tag }`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)('>'), true), (0, util_1.startLoose)((0, combinator_1.context)((() => {
|
|
7489
7489
|
switch (tag) {
|
|
7490
7490
|
case 'sup':
|
|
7491
7491
|
case 'sub':
|
|
@@ -7507,11 +7507,11 @@ require = function () {
|
|
|
7507
7507
|
default:
|
|
7508
7508
|
return {};
|
|
7509
7509
|
}
|
|
7510
|
-
})(), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`)))
|
|
7510
|
+
})(), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`)), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest, context) => [
|
|
7511
7511
|
[elem(tag, as, (0, util_1.trimEndBR)((0, typed_dom_1.defrag)(bs)), cs, context)],
|
|
7512
7512
|
rest
|
|
7513
7513
|
])), ([, tag]) => tag)),
|
|
7514
|
-
(0, combinator_1.match)(/^(?=<([a-z]+)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${ tag }`, `</${ tag }>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${ tag }`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)('>'), true), (0, util_1.startLoose)((0,
|
|
7514
|
+
(0, combinator_1.match)(/^(?=<([a-z]+)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${ tag }`, `</${ tag }>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${ tag }`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)('>'), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest) => [
|
|
7515
7515
|
[elem(tag, as, (0, util_1.trimEndBR)((0, typed_dom_1.defrag)(bs)), cs, {})],
|
|
7516
7516
|
rest
|
|
7517
7517
|
], ([as, bs], rest) => as.length === 1 ? [
|
|
@@ -7529,14 +7529,14 @@ require = function () {
|
|
|
7529
7529
|
case 'sub':
|
|
7530
7530
|
switch (true) {
|
|
7531
7531
|
case (_b = (_a = context.state) === null || _a === void 0 ? void 0 : _a.in) === null || _b === void 0 ? void 0 : _b.supsub:
|
|
7532
|
-
return invalid('nest', `<${ tag }> HTML tag cannot be used in <sup
|
|
7532
|
+
return invalid('nest', `<${ tag }> HTML tag cannot be used in <sup> or <sub> HTML tag.`, as, bs, cs);
|
|
7533
7533
|
}
|
|
7534
7534
|
break;
|
|
7535
7535
|
case 'small':
|
|
7536
7536
|
switch (true) {
|
|
7537
7537
|
case (_d = (_c = context.state) === null || _c === void 0 ? void 0 : _c.in) === null || _d === void 0 ? void 0 : _d.supsub:
|
|
7538
7538
|
case (_f = (_e = context.state) === null || _e === void 0 ? void 0 : _e.in) === null || _f === void 0 ? void 0 : _f.small:
|
|
7539
|
-
return invalid('nest', `<${ tag }> HTML tag cannot be used in <sup
|
|
7539
|
+
return invalid('nest', `<${ tag }> HTML tag cannot be used in <sup>, <sub>, or <small> HTML tag.`, as, bs, cs);
|
|
7540
7540
|
}
|
|
7541
7541
|
break;
|
|
7542
7542
|
}
|
|
@@ -7672,7 +7672,7 @@ require = function () {
|
|
|
7672
7672
|
(0, combinator_1.context)({ syntax: { inline: { link: false } } }, (0, combinator_1.dup)((0, combinator_1.union)([
|
|
7673
7673
|
(0, combinator_1.surround)('[', inline_1.media, ']'),
|
|
7674
7674
|
(0, combinator_1.surround)('[', inline_1.shortmedia, ']'),
|
|
7675
|
-
(0, combinator_1.surround)('[', (0, util_1.startLoose)((0,
|
|
7675
|
+
(0, combinator_1.surround)('[', (0, util_1.startLoose)((0, combinator_1.context)({
|
|
7676
7676
|
syntax: {
|
|
7677
7677
|
inline: {
|
|
7678
7678
|
annotation: false,
|
|
@@ -7683,18 +7683,18 @@ require = function () {
|
|
|
7683
7683
|
autolink: false
|
|
7684
7684
|
}
|
|
7685
7685
|
}
|
|
7686
|
-
}, (0, combinator_1.some)(inline_1.inline, ']', /^\\?\n/)))
|
|
7686
|
+
}, (0, combinator_1.some)(inline_1.inline, ']', /^\\?\n/)), ']'), ']', true)
|
|
7687
7687
|
]))),
|
|
7688
7688
|
(0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([
|
|
7689
7689
|
exports.uri,
|
|
7690
7690
|
(0, combinator_1.some)(exports.option)
|
|
7691
7691
|
]), /^[^\S\n]?}/))
|
|
7692
7692
|
])))), ([params, content = []], rest, context) => {
|
|
7693
|
-
var _a, _b;
|
|
7693
|
+
var _a, _b, _c, _d, _e;
|
|
7694
7694
|
if ((0, parser_1.eval)((0, combinator_1.some)(autolink_1.autolink)((0, util_1.stringify)(content), context), []).some(node => typeof node === 'object'))
|
|
7695
7695
|
return;
|
|
7696
7696
|
const INSECURE_URI = params.shift();
|
|
7697
|
-
const el = create(INSECURE_URI, (0, util_1.trimNode)((0, typed_dom_1.defrag)(content)), new url_1.ReadonlyURL(resolve(INSECURE_URI, context.host
|
|
7697
|
+
const el = create(INSECURE_URI, (0, util_1.trimNode)((0, typed_dom_1.defrag)(content)), new url_1.ReadonlyURL(resolve(INSECURE_URI, (_a = context.host) !== null && _a !== void 0 ? _a : global_1.location, (_c = (_b = context.url) !== null && _b !== void 0 ? _b : context.host) !== null && _c !== void 0 ? _c : global_1.location), ((_d = context.host) === null || _d === void 0 ? void 0 : _d.href) || global_1.location.href), ((_e = context.host) === null || _e === void 0 ? void 0 : _e.origin) || global_1.location.origin);
|
|
7698
7698
|
if (el.classList.contains('invalid'))
|
|
7699
7699
|
return [
|
|
7700
7700
|
[el],
|
|
@@ -7716,40 +7716,41 @@ require = function () {
|
|
|
7716
7716
|
(0, combinator_1.fmap)((0, source_1.str)(/^[^\S\n]+[^\n{}]+/), opt => [` \\${ opt.slice(1) }`])
|
|
7717
7717
|
]);
|
|
7718
7718
|
function resolve(uri, host, source) {
|
|
7719
|
-
var _a;
|
|
7720
7719
|
switch (true) {
|
|
7721
7720
|
case uri.slice(0, 2) === '^/':
|
|
7722
|
-
const
|
|
7723
|
-
return
|
|
7721
|
+
const last = host.pathname.slice(host.pathname.lastIndexOf('/') + 1);
|
|
7722
|
+
return last.includes('.') && /^[0-9]*[a-z][0-9a-z]*$/i.test(last.slice(last.lastIndexOf('.') + 1)) ? `${ host.pathname.slice(0, -last.length) }${ uri.slice(2) }` : `${ host.pathname.replace(/\/?$/, '/') }${ uri.slice(2) }`;
|
|
7724
7723
|
case host.origin === source.origin && host.pathname === source.pathname:
|
|
7725
7724
|
case uri.slice(0, 2) === '//':
|
|
7726
7725
|
return uri;
|
|
7727
7726
|
default:
|
|
7728
7727
|
const target = new url_1.ReadonlyURL(uri, source.href);
|
|
7729
|
-
return target.origin ===
|
|
7728
|
+
return target.origin === host.origin ? target.href.slice(target.origin.length) : target.href;
|
|
7730
7729
|
}
|
|
7731
7730
|
}
|
|
7732
7731
|
exports.resolve = resolve;
|
|
7733
|
-
function
|
|
7734
|
-
return pathname[pathname.length - 1] === '/' ? pathname : pathname + '/';
|
|
7735
|
-
}
|
|
7736
|
-
function create(address, content, uri, origin) {
|
|
7732
|
+
function create(INSECURE_URI, content, uri, origin) {
|
|
7737
7733
|
let type;
|
|
7738
7734
|
let description;
|
|
7739
7735
|
switch (uri.protocol) {
|
|
7740
7736
|
case 'http:':
|
|
7741
7737
|
case 'https:':
|
|
7738
|
+
if (INSECURE_URI.slice(0, 2) === '^/' && /(?:\/\.\.?)(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/)))) {
|
|
7739
|
+
type = 'argument';
|
|
7740
|
+
description = 'Subresource paths cannot contain dot-segments.';
|
|
7741
|
+
break;
|
|
7742
|
+
}
|
|
7742
7743
|
return (0, typed_dom_1.html)('a', {
|
|
7743
7744
|
href: uri.source,
|
|
7744
7745
|
target: undefined || uri.origin !== origin || typeof content[0] === 'object' && content[0].classList.contains('media') ? '_blank' : undefined
|
|
7745
|
-
}, content.length === 0 ? decode(
|
|
7746
|
+
}, content.length === 0 ? decode(INSECURE_URI) : content);
|
|
7746
7747
|
case 'tel:':
|
|
7747
7748
|
if (content.length === 0) {
|
|
7748
|
-
content = [
|
|
7749
|
+
content = [INSECURE_URI];
|
|
7749
7750
|
}
|
|
7750
7751
|
const pattern = /^(?:tel:)?(?:\+(?!0))?\d+(?:-\d+)*$/i;
|
|
7751
7752
|
switch (true) {
|
|
7752
|
-
case content.length === 1 && typeof content[0] === 'string' && pattern.test(
|
|
7753
|
+
case content.length === 1 && typeof content[0] === 'string' && pattern.test(INSECURE_URI) && pattern.test(content[0]) && INSECURE_URI.replace(/[^+\d]/g, '') === content[0].replace(/[^+\d]/g, ''):
|
|
7753
7754
|
return (0, typed_dom_1.html)('a', { href: uri.source }, content);
|
|
7754
7755
|
}
|
|
7755
7756
|
type = 'content';
|
|
@@ -7761,7 +7762,7 @@ require = function () {
|
|
|
7761
7762
|
'data-invalid-syntax': 'link',
|
|
7762
7763
|
'data-invalid-type': type !== null && type !== void 0 ? type : type = 'argument',
|
|
7763
7764
|
'data-invalid-description': description !== null && description !== void 0 ? description : description = 'Invalid protocol.'
|
|
7764
|
-
}, content.length === 0 ?
|
|
7765
|
+
}, content.length === 0 ? INSECURE_URI : content);
|
|
7765
7766
|
}
|
|
7766
7767
|
function decode(uri) {
|
|
7767
7768
|
if (uri.indexOf('%') === -1)
|
|
@@ -7907,24 +7908,23 @@ require = function () {
|
|
|
7907
7908
|
[''],
|
|
7908
7909
|
as
|
|
7909
7910
|
]), ([[text]]) => text === '' || text.trim() !== ''), ([[text], params], rest, context) => {
|
|
7910
|
-
var _a, _b, _c, _d;
|
|
7911
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
7911
7912
|
const INSECURE_URI = params.shift();
|
|
7912
|
-
const url = new url_1.ReadonlyURL((0, link_1.resolve)(INSECURE_URI, context.host
|
|
7913
|
-
|
|
7914
|
-
const
|
|
7915
|
-
const el = cache && cached ? cache.get(url.href).cloneNode(true) : (0, typed_dom_1.html)('img', {
|
|
7913
|
+
const url = new url_1.ReadonlyURL((0, link_1.resolve)(INSECURE_URI, (_a = context.host) !== null && _a !== void 0 ? _a : global_1.location, (_c = (_b = context.url) !== null && _b !== void 0 ? _b : context.host) !== null && _c !== void 0 ? _c : global_1.location), ((_d = context.host) === null || _d === void 0 ? void 0 : _d.href) || global_1.location.href);
|
|
7914
|
+
let cache;
|
|
7915
|
+
const el = global_1.undefined || (cache = (_g = (_f = (_e = context.caches) === null || _e === void 0 ? void 0 : _e.media) === null || _f === void 0 ? void 0 : _f.get(url.href)) === null || _g === void 0 ? void 0 : _g.cloneNode(true)) || (0, typed_dom_1.html)('img', {
|
|
7916
7916
|
class: 'media',
|
|
7917
7917
|
'data-src': url.source,
|
|
7918
7918
|
alt: text
|
|
7919
7919
|
});
|
|
7920
|
-
if (!
|
|
7920
|
+
if (!cache && !sanitize(url, el))
|
|
7921
7921
|
return [
|
|
7922
7922
|
[el],
|
|
7923
7923
|
rest
|
|
7924
7924
|
];
|
|
7925
|
-
|
|
7925
|
+
(cache === null || cache === void 0 ? void 0 : cache.hasAttribute('alt')) && (cache === null || cache === void 0 ? void 0 : cache.setAttribute('alt', text));
|
|
7926
7926
|
(0, typed_dom_1.define)(el, (0, html_1.attributes)('media', (0, array_1.push)([], el.classList), optspec, params));
|
|
7927
|
-
if (((
|
|
7927
|
+
if (((_j = (_h = context.syntax) === null || _h === void 0 ? void 0 : _h.inline) === null || _j === void 0 ? void 0 : _j.link) === false || cache && cache.tagName !== 'IMG')
|
|
7928
7928
|
return [
|
|
7929
7929
|
[el],
|
|
7930
7930
|
rest
|
|
@@ -7970,18 +7970,29 @@ require = function () {
|
|
|
7970
7970
|
link_1.option
|
|
7971
7971
|
]);
|
|
7972
7972
|
function sanitize(uri, target) {
|
|
7973
|
+
if (/^\.\.?\//.test(uri.source)) {
|
|
7974
|
+
(0, typed_dom_1.define)(target, {
|
|
7975
|
+
class: void target.classList.add('invalid'),
|
|
7976
|
+
'data-invalid-syntax': 'media',
|
|
7977
|
+
'data-invalid-type': 'argument',
|
|
7978
|
+
'data-invalid-description': 'Relative paths cannot be used with media syntax; Use subresource paths instead.'
|
|
7979
|
+
});
|
|
7980
|
+
return false;
|
|
7981
|
+
}
|
|
7973
7982
|
switch (uri.protocol) {
|
|
7974
7983
|
case 'http:':
|
|
7975
7984
|
case 'https:':
|
|
7976
|
-
|
|
7985
|
+
break;
|
|
7986
|
+
default:
|
|
7987
|
+
(0, typed_dom_1.define)(target, {
|
|
7988
|
+
class: void target.classList.add('invalid'),
|
|
7989
|
+
'data-invalid-syntax': 'media',
|
|
7990
|
+
'data-invalid-type': 'argument',
|
|
7991
|
+
'data-invalid-description': 'Invalid protocol.'
|
|
7992
|
+
});
|
|
7993
|
+
return false;
|
|
7977
7994
|
}
|
|
7978
|
-
|
|
7979
|
-
class: void target.classList.add('invalid'),
|
|
7980
|
-
'data-invalid-syntax': 'media',
|
|
7981
|
-
'data-invalid-type': 'argument',
|
|
7982
|
-
'data-invalid-description': 'Invalid protocol.'
|
|
7983
|
-
});
|
|
7984
|
-
return false;
|
|
7995
|
+
return true;
|
|
7985
7996
|
}
|
|
7986
7997
|
},
|
|
7987
7998
|
{
|
|
@@ -8011,7 +8022,7 @@ require = function () {
|
|
|
8011
8022
|
exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('[[', ']]', '\n', (0, combinator_1.fmap)((0, combinator_1.surround)('[[', (0, combinator_1.guard)(context => {
|
|
8012
8023
|
var _a, _b, _c;
|
|
8013
8024
|
return (_c = (_b = (_a = context.syntax) === null || _a === void 0 ? void 0 : _a.inline) === null || _b === void 0 ? void 0 : _b.reference) !== null && _c !== void 0 ? _c : true;
|
|
8014
|
-
}, (0, util_1.startLoose)((0,
|
|
8025
|
+
}, (0, util_1.startLoose)((0, combinator_1.context)({
|
|
8015
8026
|
syntax: {
|
|
8016
8027
|
inline: {
|
|
8017
8028
|
annotation: false,
|
|
@@ -8030,8 +8041,8 @@ require = function () {
|
|
|
8030
8041
|
''
|
|
8031
8042
|
]),
|
|
8032
8043
|
(0, combinator_1.some)(inline_1.inline, ']', /^\\?\n/)
|
|
8033
|
-
]))))
|
|
8034
|
-
const abbr = (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.verify)((0, combinator_1.surround)('^', (0, combinator_1.union)([(0, source_1.str)(/^(?![0-9]+\s?[|\]])[0-9A-Za-z]+(?:(?:-|(?=\W)(?!'\d)'?(?!\.\d)\.?(?!,\S),? ?)[0-9A-Za-z]+)*(?:-|'?\.?,? ?)?/)]), /^\|?(?=]])|^\|[^\S\n]
|
|
8044
|
+
])), ']]')), ']]'), ns => [(0, typed_dom_1.html)('sup', attributes(ns), (0, util_1.trimNode)((0, typed_dom_1.defrag)(ns)))]))));
|
|
8045
|
+
const abbr = (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.verify)((0, combinator_1.surround)('^', (0, combinator_1.union)([(0, source_1.str)(/^(?![0-9]+\s?[|\]])[0-9A-Za-z]+(?:(?:-|(?=\W)(?!'\d)'?(?!\.\d)\.?(?!,\S),? ?)[0-9A-Za-z]+)*(?:-|'?\.?,? ?)?/)]), /^\|?(?=]])|^\|[^\S\n]/), (_, rest, context) => (0, util_1.isStartLoose)(rest, context)), ([source]) => [(0, typed_dom_1.html)('abbr', source)]));
|
|
8035
8046
|
function attributes(ns) {
|
|
8036
8047
|
return typeof ns[0] === 'object' && ns[0].tagName === 'ABBR' ? {
|
|
8037
8048
|
class: 'reference',
|
|
@@ -8942,7 +8953,7 @@ require = function () {
|
|
|
8942
8953
|
function (_dereq_, module, exports) {
|
|
8943
8954
|
'use strict';
|
|
8944
8955
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
8945
|
-
exports.stringify = exports.trimEndBR = exports.trimNodeEnd = exports.trimNode = exports.
|
|
8956
|
+
exports.stringify = exports.trimEndBR = exports.trimNodeEnd = exports.trimNode = exports.isEndTightNodes = exports.isStartTightNodes = exports.startTight = exports.isStartLoose = exports.startLoose = exports.visualize = void 0;
|
|
8946
8957
|
const global_1 = _dereq_('spica/global');
|
|
8947
8958
|
const parser_1 = _dereq_('../combinator/data/parser');
|
|
8948
8959
|
const combinator_1 = _dereq_('../combinator');
|
|
@@ -9017,15 +9028,18 @@ require = function () {
|
|
|
9017
9028
|
}
|
|
9018
9029
|
return false;
|
|
9019
9030
|
}
|
|
9020
|
-
function startLoose(parser) {
|
|
9021
|
-
return (source, context) => isStartLoose(source, context) ? parser(source, context) : global_1.undefined;
|
|
9031
|
+
function startLoose(parser, except) {
|
|
9032
|
+
return (source, context) => isStartLoose(source, context, except) ? parser(source, context) : global_1.undefined;
|
|
9022
9033
|
}
|
|
9023
9034
|
exports.startLoose = startLoose;
|
|
9024
|
-
function isStartLoose(source, context) {
|
|
9035
|
+
function isStartLoose(source, context, except) {
|
|
9036
|
+
var _a;
|
|
9037
|
+
source && (source = source.replace(/^[^\S\n]+/, ''));
|
|
9025
9038
|
if (source === '')
|
|
9026
9039
|
return true;
|
|
9027
|
-
return
|
|
9040
|
+
return source.slice(0, (_a = except === null || except === void 0 ? void 0 : except.length) !== null && _a !== void 0 ? _a : 0) !== except && isStartTight(source, context);
|
|
9028
9041
|
}
|
|
9042
|
+
exports.isStartLoose = isStartLoose;
|
|
9029
9043
|
function startTight(parser) {
|
|
9030
9044
|
return (source, context) => isStartTight(source, context) ? parser(source, context) : global_1.undefined;
|
|
9031
9045
|
}
|
|
@@ -9064,7 +9078,6 @@ require = function () {
|
|
|
9064
9078
|
return source[0].trimStart() !== '';
|
|
9065
9079
|
}
|
|
9066
9080
|
}
|
|
9067
|
-
exports.isStartTight = isStartTight;
|
|
9068
9081
|
function isStartTightNodes(nodes) {
|
|
9069
9082
|
if (nodes.length === 0)
|
|
9070
9083
|
return true;
|
|
@@ -9078,18 +9091,6 @@ require = function () {
|
|
|
9078
9091
|
return typeof nodes[last] === 'string' && nodes[last].length > 1 ? isVisible(nodes[last], -1) || isVisible(nodes[last], -2) : isVisible(nodes[last], -1) || last === 0 || isVisible(nodes[last - 1], -1);
|
|
9079
9092
|
}
|
|
9080
9093
|
exports.isEndTightNodes = isEndTightNodes;
|
|
9081
|
-
function visible(parser) {
|
|
9082
|
-
return (0, combinator_1.verify)(parser, nodes => {
|
|
9083
|
-
if (nodes.length === 0)
|
|
9084
|
-
return true;
|
|
9085
|
-
for (let i = 0; i < nodes.length; ++i) {
|
|
9086
|
-
if (isVisible(nodes[i]))
|
|
9087
|
-
return true;
|
|
9088
|
-
}
|
|
9089
|
-
return false;
|
|
9090
|
-
});
|
|
9091
|
-
}
|
|
9092
|
-
exports.visible = visible;
|
|
9093
9094
|
function isVisible(node, position) {
|
|
9094
9095
|
if (!node)
|
|
9095
9096
|
return false;
|
|
@@ -9216,8 +9217,6 @@ require = function () {
|
|
|
9216
9217
|
}));
|
|
9217
9218
|
function render(source, opts = {}) {
|
|
9218
9219
|
opts = extend(opts);
|
|
9219
|
-
if (source.classList.contains('invalid'))
|
|
9220
|
-
return;
|
|
9221
9220
|
const base = global_1.location.href;
|
|
9222
9221
|
if (source.matches(selector))
|
|
9223
9222
|
return void render_(base, source, opts);
|
|
@@ -9228,6 +9227,8 @@ require = function () {
|
|
|
9228
9227
|
exports.render = render;
|
|
9229
9228
|
function render_(base, source, opts) {
|
|
9230
9229
|
var _a, _b, _c;
|
|
9230
|
+
if (source.classList.contains('invalid'))
|
|
9231
|
+
return;
|
|
9231
9232
|
try {
|
|
9232
9233
|
switch (true) {
|
|
9233
9234
|
case !!opts.code && !source.firstElementChild && source.matches('pre.code'):
|
package/package-lock.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "securemark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.224.0",
|
|
4
4
|
"lockfileVersion": 1,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"dependencies": {
|
|
@@ -399,9 +399,9 @@
|
|
|
399
399
|
}
|
|
400
400
|
},
|
|
401
401
|
"@npmcli/fs": {
|
|
402
|
-
"version": "1.
|
|
403
|
-
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.
|
|
404
|
-
"integrity": "sha512-
|
|
402
|
+
"version": "1.1.0",
|
|
403
|
+
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.0.tgz",
|
|
404
|
+
"integrity": "sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==",
|
|
405
405
|
"dev": true,
|
|
406
406
|
"requires": {
|
|
407
407
|
"@gar/promisify": "^1.0.1",
|
|
@@ -1338,21 +1338,21 @@
|
|
|
1338
1338
|
"dev": true
|
|
1339
1339
|
},
|
|
1340
1340
|
"body-parser": {
|
|
1341
|
-
"version": "1.19.
|
|
1342
|
-
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.
|
|
1343
|
-
"integrity": "sha512-
|
|
1341
|
+
"version": "1.19.1",
|
|
1342
|
+
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz",
|
|
1343
|
+
"integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==",
|
|
1344
1344
|
"dev": true,
|
|
1345
1345
|
"requires": {
|
|
1346
|
-
"bytes": "3.1.
|
|
1346
|
+
"bytes": "3.1.1",
|
|
1347
1347
|
"content-type": "~1.0.4",
|
|
1348
1348
|
"debug": "2.6.9",
|
|
1349
1349
|
"depd": "~1.1.2",
|
|
1350
|
-
"http-errors": "1.
|
|
1350
|
+
"http-errors": "1.8.1",
|
|
1351
1351
|
"iconv-lite": "0.4.24",
|
|
1352
1352
|
"on-finished": "~2.3.0",
|
|
1353
|
-
"qs": "6.
|
|
1354
|
-
"raw-body": "2.4.
|
|
1355
|
-
"type-is": "~1.6.
|
|
1353
|
+
"qs": "6.9.6",
|
|
1354
|
+
"raw-body": "2.4.2",
|
|
1355
|
+
"type-is": "~1.6.18"
|
|
1356
1356
|
}
|
|
1357
1357
|
},
|
|
1358
1358
|
"boxen": {
|
|
@@ -1672,9 +1672,9 @@
|
|
|
1672
1672
|
"dev": true
|
|
1673
1673
|
},
|
|
1674
1674
|
"bytes": {
|
|
1675
|
-
"version": "3.1.
|
|
1676
|
-
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.
|
|
1677
|
-
"integrity": "sha512-
|
|
1675
|
+
"version": "3.1.1",
|
|
1676
|
+
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz",
|
|
1677
|
+
"integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==",
|
|
1678
1678
|
"dev": true
|
|
1679
1679
|
},
|
|
1680
1680
|
"cacache": {
|
|
@@ -2887,9 +2887,9 @@
|
|
|
2887
2887
|
"dev": true
|
|
2888
2888
|
},
|
|
2889
2889
|
"electron-to-chromium": {
|
|
2890
|
-
"version": "1.4.
|
|
2891
|
-
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.
|
|
2892
|
-
"integrity": "sha512-
|
|
2890
|
+
"version": "1.4.16",
|
|
2891
|
+
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.16.tgz",
|
|
2892
|
+
"integrity": "sha512-BQb7FgYwnu6haWLU63/CdVW+9xhmHls3RCQUFiV4lvw3wimEHTVcUk2hkuZo76QhR8nnDdfZE7evJIZqijwPdA==",
|
|
2893
2893
|
"dev": true
|
|
2894
2894
|
},
|
|
2895
2895
|
"elliptic": {
|
|
@@ -5153,24 +5153,16 @@
|
|
|
5153
5153
|
"dev": true
|
|
5154
5154
|
},
|
|
5155
5155
|
"http-errors": {
|
|
5156
|
-
"version": "1.
|
|
5157
|
-
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.
|
|
5158
|
-
"integrity": "sha512-
|
|
5156
|
+
"version": "1.8.1",
|
|
5157
|
+
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
|
|
5158
|
+
"integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
|
|
5159
5159
|
"dev": true,
|
|
5160
5160
|
"requires": {
|
|
5161
5161
|
"depd": "~1.1.2",
|
|
5162
|
-
"inherits": "2.0.
|
|
5163
|
-
"setprototypeof": "1.
|
|
5162
|
+
"inherits": "2.0.4",
|
|
5163
|
+
"setprototypeof": "1.2.0",
|
|
5164
5164
|
"statuses": ">= 1.5.0 < 2",
|
|
5165
|
-
"toidentifier": "1.0.
|
|
5166
|
-
},
|
|
5167
|
-
"dependencies": {
|
|
5168
|
-
"inherits": {
|
|
5169
|
-
"version": "2.0.3",
|
|
5170
|
-
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
|
5171
|
-
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
|
5172
|
-
"dev": true
|
|
5173
|
-
}
|
|
5165
|
+
"toidentifier": "1.0.1"
|
|
5174
5166
|
}
|
|
5175
5167
|
},
|
|
5176
5168
|
"http-proxy": {
|
|
@@ -5621,9 +5613,9 @@
|
|
|
5621
5613
|
"dev": true
|
|
5622
5614
|
},
|
|
5623
5615
|
"is-negative-zero": {
|
|
5624
|
-
"version": "2.0.
|
|
5625
|
-
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.
|
|
5626
|
-
"integrity": "sha512-
|
|
5616
|
+
"version": "2.0.2",
|
|
5617
|
+
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
|
5618
|
+
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
|
|
5627
5619
|
"dev": true
|
|
5628
5620
|
},
|
|
5629
5621
|
"is-npm": {
|
|
@@ -5782,12 +5774,12 @@
|
|
|
5782
5774
|
"dev": true
|
|
5783
5775
|
},
|
|
5784
5776
|
"is-weakref": {
|
|
5785
|
-
"version": "1.0.
|
|
5786
|
-
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.
|
|
5787
|
-
"integrity": "sha512-
|
|
5777
|
+
"version": "1.0.2",
|
|
5778
|
+
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
|
|
5779
|
+
"integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
|
|
5788
5780
|
"dev": true,
|
|
5789
5781
|
"requires": {
|
|
5790
|
-
"call-bind": "^1.0.
|
|
5782
|
+
"call-bind": "^1.0.2"
|
|
5791
5783
|
}
|
|
5792
5784
|
},
|
|
5793
5785
|
"is-windows": {
|
|
@@ -6854,9 +6846,9 @@
|
|
|
6854
6846
|
"dev": true
|
|
6855
6847
|
},
|
|
6856
6848
|
"minipass": {
|
|
6857
|
-
"version": "3.1.
|
|
6858
|
-
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.
|
|
6859
|
-
"integrity": "sha512
|
|
6849
|
+
"version": "3.1.6",
|
|
6850
|
+
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
|
|
6851
|
+
"integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
|
|
6860
6852
|
"dev": true,
|
|
6861
6853
|
"requires": {
|
|
6862
6854
|
"yallist": "^4.0.0"
|
|
@@ -8367,9 +8359,9 @@
|
|
|
8367
8359
|
"dev": true
|
|
8368
8360
|
},
|
|
8369
8361
|
"qs": {
|
|
8370
|
-
"version": "6.
|
|
8371
|
-
"resolved": "https://registry.npmjs.org/qs/-/qs-6.
|
|
8372
|
-
"integrity": "sha512-
|
|
8362
|
+
"version": "6.9.6",
|
|
8363
|
+
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
|
|
8364
|
+
"integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==",
|
|
8373
8365
|
"dev": true
|
|
8374
8366
|
},
|
|
8375
8367
|
"querystring": {
|
|
@@ -8416,13 +8408,13 @@
|
|
|
8416
8408
|
"dev": true
|
|
8417
8409
|
},
|
|
8418
8410
|
"raw-body": {
|
|
8419
|
-
"version": "2.4.
|
|
8420
|
-
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.
|
|
8421
|
-
"integrity": "sha512-
|
|
8411
|
+
"version": "2.4.2",
|
|
8412
|
+
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz",
|
|
8413
|
+
"integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==",
|
|
8422
8414
|
"dev": true,
|
|
8423
8415
|
"requires": {
|
|
8424
|
-
"bytes": "3.1.
|
|
8425
|
-
"http-errors": "1.
|
|
8416
|
+
"bytes": "3.1.1",
|
|
8417
|
+
"http-errors": "1.8.1",
|
|
8426
8418
|
"iconv-lite": "0.4.24",
|
|
8427
8419
|
"unpipe": "1.0.0"
|
|
8428
8420
|
}
|
|
@@ -9067,9 +9059,9 @@
|
|
|
9067
9059
|
}
|
|
9068
9060
|
},
|
|
9069
9061
|
"setprototypeof": {
|
|
9070
|
-
"version": "1.
|
|
9071
|
-
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.
|
|
9072
|
-
"integrity": "sha512-
|
|
9062
|
+
"version": "1.2.0",
|
|
9063
|
+
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
|
9064
|
+
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
|
9073
9065
|
"dev": true
|
|
9074
9066
|
},
|
|
9075
9067
|
"sha.js": {
|
|
@@ -9888,9 +9880,9 @@
|
|
|
9888
9880
|
}
|
|
9889
9881
|
},
|
|
9890
9882
|
"toidentifier": {
|
|
9891
|
-
"version": "1.0.
|
|
9892
|
-
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.
|
|
9893
|
-
"integrity": "sha512-
|
|
9883
|
+
"version": "1.0.1",
|
|
9884
|
+
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
|
9885
|
+
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
|
9894
9886
|
"dev": true
|
|
9895
9887
|
},
|
|
9896
9888
|
"transformify": {
|
package/package.json
CHANGED
|
@@ -104,10 +104,6 @@ describe('Unit: parser/api/parse', () => {
|
|
|
104
104
|
'{a}',
|
|
105
105
|
'{/a}',
|
|
106
106
|
'{^/a}',
|
|
107
|
-
'{^/a/..}',
|
|
108
|
-
'{^/a/../}',
|
|
109
|
-
'{^/a?/../}',
|
|
110
|
-
'{^/a#/../}',
|
|
111
107
|
'{./a}',
|
|
112
108
|
'{../a}',
|
|
113
109
|
'{../../a}',
|
|
@@ -131,10 +127,6 @@ describe('Unit: parser/api/parse', () => {
|
|
|
131
127
|
'<p><a href="https://source/x/a" target="_blank">a</a></p>',
|
|
132
128
|
'<p><a href="https://source/a" target="_blank">/a</a></p>',
|
|
133
129
|
'<p><a href="/z/a">^/a</a></p>',
|
|
134
|
-
'<p><a href="/z/a/..">^/a/..</a></p>',
|
|
135
|
-
'<p><a href="/z/a/../">^/a/../</a></p>',
|
|
136
|
-
'<p><a href="/z/a?/../">^/a?/../</a></p>',
|
|
137
|
-
'<p><a href="/z/a#/../">^/a#/../</a></p>',
|
|
138
130
|
'<p><a href="https://source/x/a" target="_blank">./a</a></p>',
|
|
139
131
|
'<p><a href="https://source/a" target="_blank">../a</a></p>',
|
|
140
132
|
'<p><a href="https://source/a" target="_blank">../../a</a></p>',
|
|
@@ -2,13 +2,13 @@ import { undefined } from 'spica/global';
|
|
|
2
2
|
import { AnnotationParser } from '../inline';
|
|
3
3
|
import { union, some, validate, guard, context, creator, surround, lazy, fmap } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
|
-
import { startLoose,
|
|
5
|
+
import { startLoose, trimNode } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
|
|
8
8
|
export const annotation: AnnotationParser = lazy(() => creator(validate('((', '))', '\n', fmap(surround(
|
|
9
9
|
'((',
|
|
10
10
|
guard(context => context.syntax?.inline?.annotation ?? true,
|
|
11
|
-
startLoose(
|
|
11
|
+
startLoose(
|
|
12
12
|
context({ syntax: { inline: {
|
|
13
13
|
annotation: false,
|
|
14
14
|
// Redundant
|
|
@@ -20,6 +20,6 @@ export const annotation: AnnotationParser = lazy(() => creator(validate('((', ')
|
|
|
20
20
|
//link: true,
|
|
21
21
|
//autolink: true,
|
|
22
22
|
}}, state: undefined },
|
|
23
|
-
union([some(inline, ')', /^\\?\n/)]))))),
|
|
23
|
+
union([some(inline, ')', /^\\?\n/)])), '))')),
|
|
24
24
|
'))'),
|
|
25
25
|
ns => [html('sup', { class: 'annotation' }, trimNode(defrag(ns)))]))));
|
|
@@ -5,7 +5,7 @@ import { HTMLParser } from '../inline';
|
|
|
5
5
|
import { union, some, validate, context, creator, surround, match, lazy } from '../../combinator';
|
|
6
6
|
import { inline } from '../inline';
|
|
7
7
|
import { str } from '../source';
|
|
8
|
-
import { startLoose,
|
|
8
|
+
import { startLoose, trimEndBR } from '../util';
|
|
9
9
|
import { html as h, defrag } from 'typed-dom';
|
|
10
10
|
import { memoize } from 'spica/memoize';
|
|
11
11
|
import { Cache } from 'spica/cache';
|
|
@@ -39,7 +39,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
|
|
|
39
39
|
validate(`<${tag}`, `</${tag}>`,
|
|
40
40
|
surround<HTMLParser.TagParser, string>(surround(
|
|
41
41
|
str(`<${tag}`), some(attribute), str('>'), true),
|
|
42
|
-
startLoose(
|
|
42
|
+
startLoose(
|
|
43
43
|
context((() => {
|
|
44
44
|
switch (tag) {
|
|
45
45
|
case 'sup':
|
|
@@ -63,7 +63,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
|
|
|
63
63
|
return {};
|
|
64
64
|
}
|
|
65
65
|
})(),
|
|
66
|
-
some(union([inline]), `</${tag}>`)))
|
|
66
|
+
some(union([inline]), `</${tag}>`)), `</${tag}>`),
|
|
67
67
|
str(`</${tag}>`), false,
|
|
68
68
|
([as, bs, cs], rest, context) =>
|
|
69
69
|
[[elem(tag, as, trimEndBR(defrag(bs)), cs, context)], rest])),
|
|
@@ -75,7 +75,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
|
|
|
75
75
|
validate(`<${tag}`, `</${tag}>`,
|
|
76
76
|
surround<HTMLParser.TagParser, string>(surround(
|
|
77
77
|
str(`<${tag}`), some(attribute), str('>'), true),
|
|
78
|
-
startLoose(
|
|
78
|
+
startLoose(some(union([inline]), `</${tag}>`), `</${tag}>`),
|
|
79
79
|
str(`</${tag}>`), false,
|
|
80
80
|
([as, bs, cs], rest) =>
|
|
81
81
|
[[elem(tag, as, trimEndBR(defrag(bs)), cs, {})], rest],
|
|
@@ -99,14 +99,14 @@ function elem(tag: string, as: (HTMLElement | string)[], bs: (HTMLElement | stri
|
|
|
99
99
|
case 'sub':
|
|
100
100
|
switch (true) {
|
|
101
101
|
case context.state?.in?.supsub:
|
|
102
|
-
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup
|
|
102
|
+
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup> or <sub> HTML tag.`, as, bs, cs);
|
|
103
103
|
}
|
|
104
104
|
break;
|
|
105
105
|
case 'small':
|
|
106
106
|
switch (true) {
|
|
107
107
|
case context.state?.in?.supsub:
|
|
108
108
|
case context.state?.in?.small:
|
|
109
|
-
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup
|
|
109
|
+
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup>, <sub>, or <small> HTML tag.`, as, bs, cs);
|
|
110
110
|
}
|
|
111
111
|
break;
|
|
112
112
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { link } from './link';
|
|
2
2
|
import { some } from '../../combinator';
|
|
3
3
|
import { inspect } from '../../debug.test';
|
|
4
|
+
import { MarkdownParser } from '../../../markdown';
|
|
4
5
|
|
|
5
6
|
describe('Unit: parser/inline/link', () => {
|
|
6
7
|
describe('link', () => {
|
|
7
|
-
const parser = (source: string) => some(link)(source,
|
|
8
|
+
const parser = (source: string, context: MarkdownParser.Context = {}) => some(link)(source, context);
|
|
8
9
|
|
|
9
10
|
it('xss', () => {
|
|
10
11
|
assert.deepStrictEqual(inspect(parser('[]{javascript:alert}')), [['<a class="invalid">javascript:alert</a>'], '']);
|
|
@@ -89,10 +90,28 @@ describe('Unit: parser/inline/link', () => {
|
|
|
89
90
|
assert.deepStrictEqual(inspect(parser('[]{\\b}')), [[`<a href="\\b">\\b</a>`], '']);
|
|
90
91
|
assert.deepStrictEqual(inspect(parser('[]{?b=c+d&\\#}')), [['<a href="?b=c+d&\\#">?b=c+d&\\#</a>'], '']);
|
|
91
92
|
assert.deepStrictEqual(inspect(parser('[]{?&}')), [['<a href="?&amp;">?&amp;</a>'], '']);
|
|
92
|
-
assert.deepStrictEqual(inspect(parser('[]{./b}')), [['<a href="./b">./b</a>'], '']);
|
|
93
|
-
assert.deepStrictEqual(inspect(parser('[]{^/b}')), [[`<a href="/b">^/b</a>`], '']);
|
|
94
93
|
assert.deepStrictEqual(inspect(parser('[]{#}')), [['<a href="#">#</a>'], '']);
|
|
95
94
|
assert.deepStrictEqual(inspect(parser('[]{#b}')), [['<a href="#b">#b</a>'], '']);
|
|
95
|
+
assert.deepStrictEqual(inspect(parser('[]{./b}')), [['<a href="./b">./b</a>'], '']);
|
|
96
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}')), [[`<a href="/b">^/b</a>`], '']);
|
|
97
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b/.}')), [[`<a class="invalid">^/b/.</a>`], '']);
|
|
98
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b/./}')), [[`<a class="invalid">^/b/./</a>`], '']);
|
|
99
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b/..}')), [[`<a class="invalid">^/b/..</a>`], '']);
|
|
100
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b/../}')), [[`<a class="invalid">^/b/../</a>`], '']);
|
|
101
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b/../..}')), [[`<a class="invalid">^/b/../..</a>`], '']);
|
|
102
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b/../c}')), [[`<a class="invalid">^/b/../c</a>`], '']);
|
|
103
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b/../c/..}')), [[`<a class="invalid">^/b/../c/..</a>`], '']);
|
|
104
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b?/../}')), [[`<a href="/b?/../">^/b?/../</a>`], '']);
|
|
105
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b#/../}')), [[`<a href="/b#/../">^/b#/../</a>`], '']);
|
|
106
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}', { host: new URL('/dir', location.origin) })), [[`<a href="/dir/b">^/b</a>`], '']);
|
|
107
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}', { host: new URL('/dir/', location.origin) })), [[`<a href="/dir/b">^/b</a>`], '']);
|
|
108
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}', { host: new URL('/folder/doc.md', location.origin) })), [[`<a href="/folder/b">^/b</a>`], '']);
|
|
109
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}', { host: new URL('/folder/doc.md/', location.origin) })), [[`<a href="/folder/doc.md/b">^/b</a>`], '']);
|
|
110
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}', { host: new URL('/.file', location.origin) })), [[`<a href="/b">^/b</a>`], '']);
|
|
111
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}', { host: new URL('/0.0a', location.origin) })), [[`<a href="/b">^/b</a>`], '']);
|
|
112
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}', { host: new URL('/0.a0', location.origin) })), [[`<a href="/b">^/b</a>`], '']);
|
|
113
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}', { host: new URL('/0.0', location.origin) })), [[`<a href="/0.0/b">^/b</a>`], '']);
|
|
114
|
+
assert.deepStrictEqual(inspect(parser('[]{^/b}', { host: new URL('/0.0,0.0,0z', location.origin) })), [[`<a href="/0.0,0.0,0z/b">^/b</a>`], '']);
|
|
96
115
|
assert.deepStrictEqual(inspect(parser('[ a]{b}')), [['<a href="b">a</a>'], '']);
|
|
97
116
|
assert.deepStrictEqual(inspect(parser('[ a ]{b}')), [['<a href="b">a</a>'], '']);
|
|
98
117
|
assert.deepStrictEqual(inspect(parser('[a ]{b}')), [['<a href="b">a</a>'], '']);
|
|
@@ -7,7 +7,7 @@ import { inline, media, shortmedia } from '../inline';
|
|
|
7
7
|
import { attributes } from './html';
|
|
8
8
|
import { autolink } from '../autolink';
|
|
9
9
|
import { str } from '../source';
|
|
10
|
-
import { startLoose,
|
|
10
|
+
import { startLoose, trimNode, stringify } from '../util';
|
|
11
11
|
import { html, define, defrag } from 'typed-dom';
|
|
12
12
|
import { ReadonlyURL } from 'spica/url';
|
|
13
13
|
|
|
@@ -28,7 +28,7 @@ export const link: LinkParser = lazy(() => creator(10, bind(reverse(
|
|
|
28
28
|
surround('[', shortmedia, ']'),
|
|
29
29
|
surround(
|
|
30
30
|
'[',
|
|
31
|
-
startLoose(
|
|
31
|
+
startLoose(
|
|
32
32
|
context({ syntax: { inline: {
|
|
33
33
|
annotation: false,
|
|
34
34
|
reference: false,
|
|
@@ -39,7 +39,7 @@ export const link: LinkParser = lazy(() => creator(10, bind(reverse(
|
|
|
39
39
|
media: false,
|
|
40
40
|
autolink: false,
|
|
41
41
|
}}},
|
|
42
|
-
some(inline, ']', /^\\?\n/)))
|
|
42
|
+
some(inline, ']', /^\\?\n/)), ']'),
|
|
43
43
|
']',
|
|
44
44
|
true),
|
|
45
45
|
]))),
|
|
@@ -56,7 +56,7 @@ export const link: LinkParser = lazy(() => creator(10, bind(reverse(
|
|
|
56
56
|
INSECURE_URI,
|
|
57
57
|
trimNode(defrag(content)),
|
|
58
58
|
new ReadonlyURL(
|
|
59
|
-
resolve(INSECURE_URI, context.host
|
|
59
|
+
resolve(INSECURE_URI, context.host ?? location, context.url ?? context.host ?? location),
|
|
60
60
|
context.host?.href || location.href),
|
|
61
61
|
context.host?.origin || location.origin);
|
|
62
62
|
if (el.classList.contains('invalid')) return [[el], rest];
|
|
@@ -81,33 +81,25 @@ export function resolve(uri: string, host: URL | Location, source: URL | Locatio
|
|
|
81
81
|
assert(uri === uri.trim());
|
|
82
82
|
switch (true) {
|
|
83
83
|
case uri.slice(0, 2) === '^/':
|
|
84
|
-
const
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
const last = host.pathname.slice(host.pathname.lastIndexOf('/') + 1);
|
|
85
|
+
return last.includes('.') // isFile
|
|
86
|
+
&& /^[0-9]*[a-z][0-9a-z]*$/i.test(last.slice(last.lastIndexOf('.') + 1))
|
|
87
|
+
? `${host.pathname.slice(0, -last.length)}${uri.slice(2)}`
|
|
88
|
+
: `${host.pathname.replace(/\/?$/, '/')}${uri.slice(2)}`;
|
|
88
89
|
case host.origin === source.origin
|
|
89
90
|
&& host.pathname === source.pathname:
|
|
90
91
|
case uri.slice(0, 2) === '//':
|
|
91
92
|
return uri;
|
|
92
93
|
default:
|
|
93
94
|
const target = new ReadonlyURL(uri, source.href);
|
|
94
|
-
return target.origin ===
|
|
95
|
-
? uri
|
|
96
|
-
: target.origin === host.origin
|
|
95
|
+
return target.origin === host.origin
|
|
97
96
|
? target.href.slice(target.origin.length)
|
|
98
97
|
: target.href;
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
function fillTrailingSlash(pathname: string): string {
|
|
103
|
-
assert(pathname);
|
|
104
|
-
return pathname[pathname.length - 1] === '/'
|
|
105
|
-
? pathname
|
|
106
|
-
: pathname + '/';
|
|
107
|
-
}
|
|
108
|
-
|
|
109
101
|
function create(
|
|
110
|
-
|
|
102
|
+
INSECURE_URI: string,
|
|
111
103
|
content: readonly (string | HTMLElement)[],
|
|
112
104
|
uri: ReadonlyURL,
|
|
113
105
|
origin: string,
|
|
@@ -118,6 +110,12 @@ function create(
|
|
|
118
110
|
case 'http:':
|
|
119
111
|
case 'https:':
|
|
120
112
|
assert(uri.host);
|
|
113
|
+
if (INSECURE_URI.slice(0, 2) === '^/' &&
|
|
114
|
+
/(?:\/\.\.?)(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/)))) {
|
|
115
|
+
type = 'argument';
|
|
116
|
+
description = 'Subresource paths cannot contain dot-segments.';
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
121
119
|
return html('a',
|
|
122
120
|
{
|
|
123
121
|
href: uri.source,
|
|
@@ -128,19 +126,19 @@ function create(
|
|
|
128
126
|
: undefined,
|
|
129
127
|
},
|
|
130
128
|
content.length === 0
|
|
131
|
-
? decode(
|
|
129
|
+
? decode(INSECURE_URI)
|
|
132
130
|
: content);
|
|
133
131
|
case 'tel:':
|
|
134
132
|
if (content.length === 0) {
|
|
135
|
-
content = [
|
|
133
|
+
content = [INSECURE_URI];
|
|
136
134
|
}
|
|
137
135
|
const pattern = /^(?:tel:)?(?:\+(?!0))?\d+(?:-\d+)*$/i;
|
|
138
136
|
switch (true) {
|
|
139
137
|
case content.length === 1
|
|
140
138
|
&& typeof content[0] === 'string'
|
|
141
|
-
&& pattern.test(
|
|
139
|
+
&& pattern.test(INSECURE_URI)
|
|
142
140
|
&& pattern.test(content[0])
|
|
143
|
-
&&
|
|
141
|
+
&& INSECURE_URI.replace(/[^+\d]/g, '') === content[0].replace(/[^+\d]/g, ''):
|
|
144
142
|
return html('a', { href: uri.source }, content);
|
|
145
143
|
}
|
|
146
144
|
type = 'content';
|
|
@@ -155,7 +153,7 @@ function create(
|
|
|
155
153
|
'data-invalid-description': description ??= 'Invalid protocol.',
|
|
156
154
|
},
|
|
157
155
|
content.length === 0
|
|
158
|
-
?
|
|
156
|
+
? INSECURE_URI
|
|
159
157
|
: content);
|
|
160
158
|
}
|
|
161
159
|
|
|
@@ -47,6 +47,8 @@ describe('Unit: parser/inline/media', () => {
|
|
|
47
47
|
assert.deepStrictEqual(inspect(parser('![]{tel:1234567890}')), [['<img class="media invalid" data-src="tel:1234567890" alt="">'], '']);
|
|
48
48
|
//assert.deepStrictEqual(inspect(parser('![]{http://[::ffff:0:0%1]}')), [['<img class="media invalid" alt="">'], '']);
|
|
49
49
|
//assert.deepStrictEqual(inspect(parser('![]{http://[::ffff:0:0/96]}')), [['<img class="media invalid" alt="">'], '']);
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('![]{./a}')), [['<img class="media invalid" data-src="./a" alt="">'], '']);
|
|
51
|
+
assert.deepStrictEqual(inspect(parser('![]{../a}')), [['<img class="media invalid" data-src="../a" alt="">'], '']);
|
|
50
52
|
assert.deepStrictEqual(inspect(parser(' ![]{a}')), undefined);
|
|
51
53
|
assert.deepStrictEqual(inspect(parser('[]{/}')), undefined);
|
|
52
54
|
});
|
|
@@ -60,7 +62,6 @@ describe('Unit: parser/inline/media', () => {
|
|
|
60
62
|
assert.deepStrictEqual(inspect(parser('![]{\\}')), [['<a href="\\" target="_blank"><img class="media" data-src="\\" alt=""></a>'], '']);
|
|
61
63
|
assert.deepStrictEqual(inspect(parser('![]{\\ }')), [['<a href="\\" target="_blank"><img class="media" data-src="\\" alt=""></a>'], '']);
|
|
62
64
|
assert.deepStrictEqual(inspect(parser('![]{\\b}')), [['<a href="\\b" target="_blank"><img class="media" data-src="\\b" alt=""></a>'], '']);
|
|
63
|
-
assert.deepStrictEqual(inspect(parser('![]{./b}')), [['<a href="./b" target="_blank"><img class="media" data-src="./b" alt=""></a>'], '']);
|
|
64
65
|
assert.deepStrictEqual(inspect(parser('![]{^/b}')), [[`<a href="/b" target="_blank"><img class="media" data-src="/b" alt=""></a>`], '']);
|
|
65
66
|
assert.deepStrictEqual(inspect(parser('![ a]{b}')), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="a"></a>'], '']);
|
|
66
67
|
assert.deepStrictEqual(inspect(parser('![ a ]{b}')), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="a"></a>'], '']);
|
|
@@ -33,18 +33,19 @@ export const media: MediaParser = lazy(() => creator(10, bind(verify(fmap(open(
|
|
|
33
33
|
assert(INSECURE_URI === INSECURE_URI.trim());
|
|
34
34
|
assert(!INSECURE_URI.match(/\s/));
|
|
35
35
|
const url = new ReadonlyURL(
|
|
36
|
-
resolve(INSECURE_URI, context.host
|
|
36
|
+
resolve(INSECURE_URI, context.host ?? location, context.url ?? context.host ?? location),
|
|
37
37
|
context.host?.href || location.href);
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (!
|
|
44
|
-
|
|
38
|
+
let cache: HTMLElement | undefined;
|
|
39
|
+
const el = undefined
|
|
40
|
+
|| (cache = context.caches?.media?.get(url.href)?.cloneNode(true))
|
|
41
|
+
|| html('img', { class: 'media', 'data-src': url.source, alt: text });
|
|
42
|
+
assert(!el.matches('.invalid'));
|
|
43
|
+
if (!cache && !sanitize(url, el)) return [[el], rest];
|
|
44
|
+
assert(!el.matches('.invalid'));
|
|
45
|
+
cache?.hasAttribute('alt') && cache?.setAttribute('alt', text);
|
|
45
46
|
define(el, attributes('media', push([], el.classList), optspec, params));
|
|
46
47
|
assert(el.matches('img') || !el.matches('.invalid'));
|
|
47
|
-
if (context.syntax?.inline?.link === false ||
|
|
48
|
+
if (context.syntax?.inline?.link === false || cache && cache.tagName !== 'IMG') return [[el], rest];
|
|
48
49
|
return fmap(
|
|
49
50
|
link as MediaParser,
|
|
50
51
|
([link]) => [define(link, { target: '_blank' }, [el])])
|
|
@@ -66,18 +67,29 @@ const option: MediaParser.ParameterParser.OptionParser = union([
|
|
|
66
67
|
|
|
67
68
|
function sanitize(uri: ReadonlyURL, target: HTMLElement): boolean {
|
|
68
69
|
assert(target.tagName === 'IMG');
|
|
70
|
+
assert(!target.matches('.invalid'));
|
|
71
|
+
if (/^\.\.?\//.test(uri.source)) {
|
|
72
|
+
define(target, {
|
|
73
|
+
class: void target.classList.add('invalid'),
|
|
74
|
+
'data-invalid-syntax': 'media',
|
|
75
|
+
'data-invalid-type': 'argument',
|
|
76
|
+
'data-invalid-description': 'Relative paths cannot be used with media syntax; Use subresource paths instead.',
|
|
77
|
+
});
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
69
80
|
switch (uri.protocol) {
|
|
70
81
|
case 'http:':
|
|
71
82
|
case 'https:':
|
|
72
83
|
assert(uri.host);
|
|
73
|
-
|
|
84
|
+
break;
|
|
85
|
+
default:
|
|
86
|
+
define(target, {
|
|
87
|
+
class: void target.classList.add('invalid'),
|
|
88
|
+
'data-invalid-syntax': 'media',
|
|
89
|
+
'data-invalid-type': 'argument',
|
|
90
|
+
'data-invalid-description': 'Invalid protocol.',
|
|
91
|
+
});
|
|
92
|
+
return false;
|
|
74
93
|
}
|
|
75
|
-
|
|
76
|
-
define(target, {
|
|
77
|
-
class: void target.classList.add('invalid'),
|
|
78
|
-
'data-invalid-syntax': 'media',
|
|
79
|
-
'data-invalid-type': 'argument',
|
|
80
|
-
'data-invalid-description': 'Invalid protocol.',
|
|
81
|
-
});
|
|
82
|
-
return false;
|
|
94
|
+
return true;
|
|
83
95
|
}
|
|
@@ -3,13 +3,13 @@ import { ReferenceParser } from '../inline';
|
|
|
3
3
|
import { union, subsequence, some, validate, verify, focus, guard, context, creator, surround, lazy, fmap } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import { startLoose,
|
|
6
|
+
import { startLoose, isStartLoose, trimNode, stringify } from '../util';
|
|
7
7
|
import { html, defrag } from 'typed-dom';
|
|
8
8
|
|
|
9
9
|
export const reference: ReferenceParser = lazy(() => creator(validate('[[', ']]', '\n', fmap(surround(
|
|
10
10
|
'[[',
|
|
11
11
|
guard(context => context.syntax?.inline?.reference ?? true,
|
|
12
|
-
startLoose(
|
|
12
|
+
startLoose(
|
|
13
13
|
context({ syntax: { inline: {
|
|
14
14
|
annotation: false,
|
|
15
15
|
reference: false,
|
|
@@ -24,15 +24,15 @@ export const reference: ReferenceParser = lazy(() => creator(validate('[[', ']]'
|
|
|
24
24
|
abbr,
|
|
25
25
|
focus('^', c => [['', c], '']),
|
|
26
26
|
some(inline, ']', /^\\?\n/),
|
|
27
|
-
]))))
|
|
27
|
+
])), ']]')),
|
|
28
28
|
']]'),
|
|
29
29
|
ns => [html('sup', attributes(ns), trimNode(defrag(ns)))]))));
|
|
30
30
|
|
|
31
31
|
const abbr: ReferenceParser.AbbrParser = creator(fmap(verify(surround(
|
|
32
32
|
'^',
|
|
33
33
|
union([str(/^(?![0-9]+\s?[|\]])[0-9A-Za-z]+(?:(?:-|(?=\W)(?!'\d)'?(?!\.\d)\.?(?!,\S),? ?)[0-9A-Za-z]+)*(?:-|'?\.?,? ?)?/)]),
|
|
34
|
-
/^\|?(?=]])|^\|[^\S\n]
|
|
35
|
-
(_, rest, context) =>
|
|
34
|
+
/^\|?(?=]])|^\|[^\S\n]/),
|
|
35
|
+
(_, rest, context) => isStartLoose(rest, context)),
|
|
36
36
|
([source]) => [html('abbr', source)]));
|
|
37
37
|
|
|
38
38
|
function attributes(ns: (string | HTMLElement)[]): Record<string, string | undefined> {
|
package/src/parser/util.ts
CHANGED
|
@@ -70,16 +70,18 @@ function hasVisible(
|
|
|
70
70
|
return false;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
export function startLoose<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
74
|
-
export function startLoose<T extends HTMLElement | string>(parser: Parser<T
|
|
73
|
+
export function startLoose<P extends Parser<HTMLElement | string>>(parser: P, except?: string): P;
|
|
74
|
+
export function startLoose<T extends HTMLElement | string>(parser: Parser<T>, except?: string): Parser<T> {
|
|
75
75
|
return (source, context) =>
|
|
76
|
-
isStartLoose(source, context)
|
|
76
|
+
isStartLoose(source, context, except)
|
|
77
77
|
? parser(source, context)
|
|
78
78
|
: undefined;
|
|
79
79
|
}
|
|
80
|
-
function isStartLoose(source: string, context: MarkdownParser.Context): boolean {
|
|
80
|
+
export function isStartLoose(source: string, context: MarkdownParser.Context, except?: string): boolean {
|
|
81
|
+
source &&= source.replace(/^[^\S\n]+/, '');
|
|
81
82
|
if (source === '') return true;
|
|
82
|
-
return
|
|
83
|
+
return source.slice(0, except?.length ?? 0) !== except
|
|
84
|
+
&& isStartTight(source, context);
|
|
83
85
|
}
|
|
84
86
|
export function startTight<P extends Parser<unknown>>(parser: P): P;
|
|
85
87
|
export function startTight<T>(parser: Parser<T>): Parser<T> {
|
|
@@ -88,7 +90,7 @@ export function startTight<T>(parser: Parser<T>): Parser<T> {
|
|
|
88
90
|
? parser(source, context)
|
|
89
91
|
: undefined;
|
|
90
92
|
}
|
|
91
|
-
|
|
93
|
+
function isStartTight(source: string, context: MarkdownParser.Context): boolean {
|
|
92
94
|
if (source === '') return true;
|
|
93
95
|
switch (source[0]) {
|
|
94
96
|
case ' ':
|
|
@@ -140,16 +142,6 @@ export function isEndTightNodes(nodes: readonly (HTMLElement | string)[]): boole
|
|
|
140
142
|
: isVisible(nodes[last], -1) || last === 0 ||
|
|
141
143
|
isVisible(nodes[last - 1], -1);
|
|
142
144
|
}
|
|
143
|
-
export function visible<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
144
|
-
export function visible<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {
|
|
145
|
-
return verify(parser, nodes => {
|
|
146
|
-
if (nodes.length === 0) return true;
|
|
147
|
-
for (let i = 0; i < nodes.length; ++i) {
|
|
148
|
-
if (isVisible(nodes[i])) return true;
|
|
149
|
-
}
|
|
150
|
-
return false;
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
145
|
function isVisible(node: HTMLElement | string, position?: number): boolean {
|
|
154
146
|
if (!node) return false;
|
|
155
147
|
switch (typeof node) {
|
package/src/renderer/render.ts
CHANGED
|
@@ -12,7 +12,6 @@ const extend = reduce((opts: RenderingOptions): RenderingOptions =>
|
|
|
12
12
|
|
|
13
13
|
export function render(source: HTMLElement, opts: RenderingOptions = {}): void {
|
|
14
14
|
opts = extend(opts);
|
|
15
|
-
if (source.classList.contains('invalid')) return;
|
|
16
15
|
const base = location.href;
|
|
17
16
|
if (source.matches(selector)) return void render_(base, source, opts);
|
|
18
17
|
for (
|
|
@@ -23,7 +22,7 @@ export function render(source: HTMLElement, opts: RenderingOptions = {}): void {
|
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
function render_(base: string, source: HTMLElement, opts: RenderingOptions): void {
|
|
26
|
-
|
|
25
|
+
if (source.classList.contains('invalid')) return;
|
|
27
26
|
try {
|
|
28
27
|
switch (true) {
|
|
29
28
|
case !!opts.code
|