securemark 0.235.2 → 0.237.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 +12 -0
- package/dist/securemark.js +200 -112
- package/karma.conf.js +1 -1
- package/markdown.d.ts +11 -10
- package/package-lock.json +111 -98
- package/package.json +3 -3
- package/src/debug.test.ts +3 -1
- package/src/parser/api/bind.ts +7 -3
- package/src/parser/api/parse.test.ts +3 -3
- package/src/parser/api/parse.ts +8 -11
- package/src/parser/block/blockquote.test.ts +1 -1
- package/src/parser/block/codeblock.ts +1 -1
- package/src/parser/block/dlist.ts +1 -3
- package/src/parser/block/extension/aside.test.ts +1 -1
- package/src/parser/block/extension/aside.ts +2 -2
- package/src/parser/block/extension/example.test.ts +2 -2
- package/src/parser/block/extension/example.ts +2 -2
- package/src/parser/block/extension/fig.test.ts +22 -20
- package/src/parser/block/extension/figure.test.ts +33 -31
- package/src/parser/block/extension/figure.ts +32 -3
- package/src/parser/block/extension/message.ts +2 -2
- package/src/parser/block/extension/placeholder.ts +1 -1
- package/src/parser/block/extension/table.ts +5 -5
- package/src/parser/block/extension.ts +1 -1
- package/src/parser/block/heading.ts +1 -3
- package/src/parser/block/ilist.ts +1 -1
- package/src/parser/block/mathblock.ts +1 -1
- package/src/parser/block/olist.test.ts +8 -0
- package/src/parser/block/olist.ts +7 -7
- package/src/parser/block/paragraph.test.ts +1 -1
- package/src/parser/block/reply/cite.test.ts +4 -0
- package/src/parser/block/reply/cite.ts +1 -0
- package/src/parser/block/reply/quote.ts +1 -1
- package/src/parser/block/table.ts +1 -1
- package/src/parser/block/ulist.test.ts +8 -0
- package/src/parser/block/ulist.ts +7 -7
- package/src/parser/header.ts +1 -1
- package/src/parser/inline/deletion.ts +1 -1
- package/src/parser/inline/emphasis.ts +1 -1
- package/src/parser/inline/emstrong.ts +3 -3
- package/src/parser/inline/extension/indexee.ts +8 -8
- package/src/parser/inline/extension/placeholder.ts +1 -1
- package/src/parser/inline/html.ts +7 -7
- package/src/parser/inline/htmlentity.test.ts +1 -1
- package/src/parser/inline/htmlentity.ts +18 -11
- package/src/parser/inline/insertion.ts +1 -1
- package/src/parser/inline/link.ts +4 -4
- package/src/parser/inline/mark.ts +1 -1
- package/src/parser/inline/math.ts +1 -1
- package/src/parser/inline/media.ts +3 -3
- package/src/parser/inline/reference.ts +1 -1
- package/src/parser/inline/ruby.ts +2 -2
- package/src/parser/inline/strong.ts +1 -1
- package/src/parser/inline.ts +2 -0
- package/src/parser/processor/figure.test.ts +33 -29
- package/src/parser/processor/figure.ts +25 -3
- package/src/parser/processor/footnote.ts +3 -3
- package/src/parser/util.ts +1 -1
|
@@ -26,7 +26,7 @@ export const quote: ReplyParser.QuoteParser = lazy(() => creator(block(fmap(vali
|
|
|
26
26
|
class: 'quote invalid',
|
|
27
27
|
'data-invalid-syntax': 'quote',
|
|
28
28
|
'data-invalid-type': 'syntax',
|
|
29
|
-
'data-invalid-
|
|
29
|
+
'data-invalid-message': `Missing the whitespace after "${ns[0].split(/[^>]/, 1)[0]}"`,
|
|
30
30
|
},
|
|
31
31
|
defrag(ns)),
|
|
32
32
|
html('br'),
|
|
@@ -31,7 +31,7 @@ const row = <P extends CellParser | AlignParser>(parser: P, optional: boolean):
|
|
|
31
31
|
class: 'invalid',
|
|
32
32
|
'data-invalid-syntax': 'tablerow',
|
|
33
33
|
'data-invalid-type': 'syntax',
|
|
34
|
-
'data-invalid-
|
|
34
|
+
'data-invalid-message': 'Invalid table row',
|
|
35
35
|
}, [html('td', source.replace('\n', ''))])
|
|
36
36
|
], ''])));
|
|
37
37
|
|
|
@@ -66,6 +66,14 @@ describe('Unit: parser/block/ulist', () => {
|
|
|
66
66
|
assert.deepStrictEqual(inspect(parser('- [X] 1')), [['<ul class="checklist"><li><span class="checkbox">☑</span>1</li></ul>'], '']);
|
|
67
67
|
});
|
|
68
68
|
|
|
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 [#b]')), [['<ul><li id="index:b">a<span class="indexer" data-index="b"></span></li></ul>'], '']);
|
|
72
|
+
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 [#b]')), [['<ul class="checklist"><li id="index:b"><span class="checkbox">☐</span>a<span class="indexer" data-index="b"></span></li></ul>'], '']);
|
|
74
|
+
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>'], '']);
|
|
75
|
+
});
|
|
76
|
+
|
|
69
77
|
});
|
|
70
78
|
|
|
71
79
|
});
|
|
@@ -2,7 +2,7 @@ import { UListParser } from '../block';
|
|
|
2
2
|
import { union, inits, subsequence, some, block, line, validate, indent, focus, rewrite, context, creator, open, trim, trimStart, fallback, lazy, fmap } from '../../combinator';
|
|
3
3
|
import { olist_ } from './olist';
|
|
4
4
|
import { ilist_ } from './ilist';
|
|
5
|
-
import { inline } from '../inline';
|
|
5
|
+
import { inline, indexer, indexee } from '../inline';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
import { contentline } from '../source';
|
|
@@ -15,13 +15,13 @@ export const ulist: UListParser = lazy(() => block(validate(
|
|
|
15
15
|
export const ulist_: UListParser = lazy(() => block(fmap(validate(
|
|
16
16
|
/^-(?=$|\s)/,
|
|
17
17
|
some(creator(union([
|
|
18
|
-
fmap(fallback(
|
|
18
|
+
indexee(fmap(fallback(
|
|
19
19
|
inits([
|
|
20
|
-
line(open(/^-(?:$|\s)/, trim(subsequence([checkbox, trimStart(some(inline))])), true)),
|
|
20
|
+
line(open(/^-(?:$|\s)/, trim(subsequence([checkbox, trimStart(some(union([indexer, inline])))])), true)),
|
|
21
21
|
indent(union([ulist_, olist_, ilist_])),
|
|
22
22
|
]),
|
|
23
|
-
|
|
24
|
-
ns => [html('li', defrag(fillFirstLine(ns)))]),
|
|
23
|
+
invalid),
|
|
24
|
+
ns => [html('li', defrag(fillFirstLine(ns)))]), true),
|
|
25
25
|
])))),
|
|
26
26
|
es => [format(html('ul', es))])));
|
|
27
27
|
|
|
@@ -31,12 +31,12 @@ export const checkbox = focus(
|
|
|
31
31
|
html('span', { class: 'checkbox' }, source[1].trimStart() ? '☑' : '☐'),
|
|
32
32
|
], '']);
|
|
33
33
|
|
|
34
|
-
const
|
|
34
|
+
const invalid = rewrite(contentline, source => [[
|
|
35
35
|
html('span', {
|
|
36
36
|
class: 'invalid',
|
|
37
37
|
'data-invalid-syntax': 'listitem',
|
|
38
38
|
'data-invalid-type': 'syntax',
|
|
39
|
-
'data-invalid-
|
|
39
|
+
'data-invalid-message': 'Fix the indent or the head of the list item',
|
|
40
40
|
}, source.replace('\n', ''))
|
|
41
41
|
], '']);
|
|
42
42
|
|
package/src/parser/header.ts
CHANGED
|
@@ -31,7 +31,7 @@ export const header: MarkdownParser.HeaderParser = lazy(() => validate(
|
|
|
31
31
|
translate: 'no',
|
|
32
32
|
'data-invalid-syntax': 'header',
|
|
33
33
|
'data-invalid-type': 'syntax',
|
|
34
|
-
'data-invalid-
|
|
34
|
+
'data-invalid-message': 'Invalid syntax',
|
|
35
35
|
}, normalize(source)),
|
|
36
36
|
], ''],
|
|
37
37
|
]))),
|
|
@@ -9,7 +9,7 @@ import { unshift } from 'spica/array';
|
|
|
9
9
|
export const deletion: DeletionParser = lazy(() => creator(surround(
|
|
10
10
|
str('~~'),
|
|
11
11
|
some(union([
|
|
12
|
-
some(inline, blank(/\n?/,
|
|
12
|
+
some(inline, blank(/\n?/, '~~')),
|
|
13
13
|
open(/^\n?/, some(inline, '~'), true),
|
|
14
14
|
])),
|
|
15
15
|
str('~~'), false,
|
|
@@ -10,19 +10,19 @@ import { html, defrag } from 'typed-dom';
|
|
|
10
10
|
import { unshift } from 'spica/array';
|
|
11
11
|
|
|
12
12
|
const substrong: IntermediateParser<StrongParser> = lazy(() => some(union([
|
|
13
|
-
some(inline, blank('',
|
|
13
|
+
some(inline, blank('', '**')),
|
|
14
14
|
open(some(inline, '*'), inline),
|
|
15
15
|
])));
|
|
16
16
|
const subemphasis: IntermediateParser<EmphasisParser> = lazy(() => some(union([
|
|
17
17
|
strong,
|
|
18
|
-
some(inline, blank('',
|
|
18
|
+
some(inline, blank('', '*')),
|
|
19
19
|
open(some(inline, '*'), inline),
|
|
20
20
|
])));
|
|
21
21
|
|
|
22
22
|
export const emstrong: EmStrongParser = lazy(() => creator(surround(
|
|
23
23
|
str('***'),
|
|
24
24
|
startTight(some(union([
|
|
25
|
-
some(inline, blank('',
|
|
25
|
+
some(inline, blank('', '*')),
|
|
26
26
|
open(some(inline, '*'), inline),
|
|
27
27
|
]))),
|
|
28
28
|
str(/^\*{1,3}/), false,
|
|
@@ -4,9 +4,9 @@ import { Parser } from '../../../combinator/data/parser';
|
|
|
4
4
|
import { fmap } from '../../../combinator';
|
|
5
5
|
import { define } from 'typed-dom';
|
|
6
6
|
|
|
7
|
-
export function indexee<P extends Parser<unknown, MarkdownParser.Context>>(parser: P): P;
|
|
8
|
-
export function indexee(parser: Parser<HTMLElement, MarkdownParser.Context
|
|
9
|
-
return fmap(parser, ([el], _, { id }) => [define(el, { id: id !== '' && identity(text(el)) || undefined })]);
|
|
7
|
+
export function indexee<P extends Parser<unknown, MarkdownParser.Context>>(parser: P, optional?: boolean): P;
|
|
8
|
+
export function indexee(parser: Parser<HTMLElement, MarkdownParser.Context>, optional?: boolean): Parser<HTMLElement> {
|
|
9
|
+
return fmap(parser, ([el], _, { id }) => [define(el, { id: id !== '' && identity(text(el, optional)) || undefined })]);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function identity(text: string): string {
|
|
@@ -18,13 +18,13 @@ assert(identity('0'.repeat(100)).slice(6) === '0'.repeat(100));
|
|
|
18
18
|
assert(identity('0'.repeat(101)).slice(6) === '0'.repeat(97) + '...');
|
|
19
19
|
assert(identity('0'.repeat(200)).slice(6) === '0'.repeat(97) + '...');
|
|
20
20
|
|
|
21
|
-
export function text(source: HTMLElement | DocumentFragment): string {
|
|
21
|
+
export function text(source: HTMLElement | DocumentFragment, optional = false): string {
|
|
22
22
|
assert(source instanceof DocumentFragment || !source.matches('.indexer'));
|
|
23
|
-
assert(source.querySelectorAll('.indexer').length <= 1);
|
|
24
|
-
|
|
25
|
-
assert(!source.querySelector('.annotation, br'));
|
|
26
|
-
const indexer = source.querySelector('.indexer');
|
|
23
|
+
assert(source.querySelectorAll(':scope > .indexer').length <= 1);
|
|
24
|
+
const indexer = source.querySelector(':scope > .indexer');
|
|
27
25
|
if (indexer) return indexer.getAttribute('data-index')!;
|
|
26
|
+
if (optional) return '';
|
|
27
|
+
assert(!source.querySelector('.annotation, br'));
|
|
28
28
|
const target = source.cloneNode(true) as typeof source;
|
|
29
29
|
for (
|
|
30
30
|
let es = target.querySelectorAll('code[data-src], .math[data-src], .comment, rt, rp, .reference'),
|
|
@@ -19,7 +19,7 @@ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => creator
|
|
|
19
19
|
class: 'invalid',
|
|
20
20
|
'data-invalid-syntax': 'extension',
|
|
21
21
|
'data-invalid-type': 'syntax',
|
|
22
|
-
'data-invalid-
|
|
22
|
+
'data-invalid-message': 'Invalid symbol',
|
|
23
23
|
}, defrag(bs)),
|
|
24
24
|
], rest],
|
|
25
25
|
([as, bs], rest) => [unshift(as, bs), rest]))));
|
|
@@ -116,38 +116,38 @@ function elem(tag: string, as: string[], bs: (HTMLElement | string)[], cs: strin
|
|
|
116
116
|
assert(as[0][0] === '<' && as[as.length - 1].slice(-1) === '>');
|
|
117
117
|
assert(bs.length === defrag(bs).length);
|
|
118
118
|
assert(cs.length === 1);
|
|
119
|
-
if (!tags.includes(tag)) return invalid('tag', `Invalid HTML tag <${tag}
|
|
119
|
+
if (!tags.includes(tag)) return invalid('tag', `Invalid HTML tag <${tag}>`, as, bs, cs);
|
|
120
120
|
switch (tag) {
|
|
121
121
|
case 'sup':
|
|
122
122
|
case 'sub':
|
|
123
123
|
switch (true) {
|
|
124
124
|
case context.state?.in?.supsub:
|
|
125
|
-
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup> or <sub> HTML tag
|
|
125
|
+
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup> or <sub> HTML tag`, as, bs, cs);
|
|
126
126
|
}
|
|
127
127
|
break;
|
|
128
128
|
case 'small':
|
|
129
129
|
switch (true) {
|
|
130
130
|
case context.state?.in?.supsub:
|
|
131
131
|
case context.state?.in?.small:
|
|
132
|
-
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup>, <sub>, or <small> HTML tag
|
|
132
|
+
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup>, <sub>, or <small> HTML tag`, as, bs, cs);
|
|
133
133
|
}
|
|
134
134
|
break;
|
|
135
135
|
}
|
|
136
136
|
let attrs: Record<string, string | undefined> | undefined;
|
|
137
137
|
switch (true) {
|
|
138
138
|
case 'data-invalid-syntax' in (attrs = attributes('html', [], attrspec[tag], as.slice(1, -1) as string[])):
|
|
139
|
-
return invalid('attribute', 'Invalid HTML attribute
|
|
139
|
+
return invalid('attribute', 'Invalid HTML attribute', as, bs, cs);
|
|
140
140
|
default:
|
|
141
141
|
assert(attrs);
|
|
142
142
|
return h(tag as 'span', attrs, bs);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
-
function invalid(type: string,
|
|
145
|
+
function invalid(type: string, message: string, as: (HTMLElement | string)[], bs: (HTMLElement | string)[], cs: (HTMLElement | string)[]): HTMLElement {
|
|
146
146
|
return h('span', {
|
|
147
147
|
class: 'invalid',
|
|
148
148
|
'data-invalid-syntax': 'html',
|
|
149
149
|
'data-invalid-type': type,
|
|
150
|
-
'data-invalid-
|
|
150
|
+
'data-invalid-message': message,
|
|
151
151
|
}, defrag(push(unshift(as, bs), cs)));
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -187,7 +187,7 @@ export function attributes(
|
|
|
187
187
|
attrs['class'] = join(classes, ' ');
|
|
188
188
|
attrs['data-invalid-syntax'] = syntax;
|
|
189
189
|
attrs['data-invalid-type'] = 'argument';
|
|
190
|
-
attrs['data-invalid-
|
|
190
|
+
attrs['data-invalid-message'] = 'Invalid argument';
|
|
191
191
|
}
|
|
192
192
|
return attrs;
|
|
193
193
|
}
|
|
@@ -14,7 +14,6 @@ describe('Unit: parser/inline/htmlentity', () => {
|
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('& ;')), undefined);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('&\n;')), undefined);
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('&a;')), [['<span class="invalid">&a;</span>'], '']);
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('
')), undefined);
|
|
18
17
|
assert.deepStrictEqual(inspect(parser('&#;')), undefined);
|
|
19
18
|
assert.deepStrictEqual(inspect(parser('&#g;')), undefined);
|
|
20
19
|
assert.deepStrictEqual(inspect(parser('&#x;')), undefined);
|
|
@@ -36,6 +35,7 @@ describe('Unit: parser/inline/htmlentity', () => {
|
|
|
36
35
|
});
|
|
37
36
|
|
|
38
37
|
it('entity', () => {
|
|
38
|
+
assert.deepStrictEqual(inspect(parser('
')), [[' '], '']);
|
|
39
39
|
assert.deepStrictEqual(inspect(parser(' ')), [['\u00A0'], '']);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('&')), [['&'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('©')), [['©'], '']);
|
|
@@ -1,24 +1,31 @@
|
|
|
1
|
+
import { undefined } from 'spica/global';
|
|
1
2
|
import { HTMLEntityParser, UnsafeHTMLEntityParser } from '../inline';
|
|
2
3
|
import { union, validate, focus, creator, fmap } from '../../combinator';
|
|
3
4
|
import { html } from 'typed-dom';
|
|
5
|
+
import { reduce } from 'spica/memoize';
|
|
4
6
|
|
|
5
7
|
export const unsafehtmlentity: UnsafeHTMLEntityParser = creator(validate('&', focus(
|
|
6
|
-
/^&
|
|
7
|
-
|
|
8
|
-
parser.innerHTML = entity,
|
|
9
|
-
entity = parser.textContent!,
|
|
10
|
-
[[`${entity[0] !== '&' || entity.length === 1 ? '' : '\0'}${entity}`], '']
|
|
11
|
-
))(html('b')))));
|
|
8
|
+
/^&[0-9A-Za-z]+;/,
|
|
9
|
+
entity => [[parse(entity) ?? `\0${entity}`], ''])));
|
|
12
10
|
|
|
13
11
|
export const htmlentity: HTMLEntityParser = fmap(
|
|
14
12
|
union([unsafehtmlentity]),
|
|
15
|
-
([
|
|
16
|
-
|
|
13
|
+
([test]) => [
|
|
14
|
+
test[0] === '\0'
|
|
17
15
|
? html('span', {
|
|
18
16
|
class: 'invalid',
|
|
19
17
|
'data-invalid-syntax': 'htmlentity',
|
|
20
18
|
'data-invalid-type': 'syntax',
|
|
21
|
-
'data-invalid-
|
|
22
|
-
},
|
|
23
|
-
:
|
|
19
|
+
'data-invalid-message': 'Invalid HTML entity',
|
|
20
|
+
}, test.slice(1))
|
|
21
|
+
: test,
|
|
24
22
|
]);
|
|
23
|
+
|
|
24
|
+
const parse = reduce((el => (entity: string): string | undefined => {
|
|
25
|
+
if (entity === '
') return ' ';
|
|
26
|
+
el.innerHTML = entity;
|
|
27
|
+
const text = el.textContent!;
|
|
28
|
+
return entity === text
|
|
29
|
+
? undefined
|
|
30
|
+
: text;
|
|
31
|
+
})(html('b')));
|
|
@@ -9,7 +9,7 @@ import { unshift } from 'spica/array';
|
|
|
9
9
|
export const insertion: InsertionParser = lazy(() => creator(surround(
|
|
10
10
|
str('++'),
|
|
11
11
|
some(union([
|
|
12
|
-
some(inline, blank(/\n?/,
|
|
12
|
+
some(inline, blank(/\n?/, '++')),
|
|
13
13
|
open(/^\n?/, some(inline, '+'), true),
|
|
14
14
|
])),
|
|
15
15
|
str('++'), false,
|
|
@@ -103,7 +103,7 @@ function elem(
|
|
|
103
103
|
origin: string,
|
|
104
104
|
): HTMLAnchorElement {
|
|
105
105
|
let type: string;
|
|
106
|
-
let
|
|
106
|
+
let message: string;
|
|
107
107
|
switch (uri.protocol) {
|
|
108
108
|
case 'http:':
|
|
109
109
|
case 'https:':
|
|
@@ -111,7 +111,7 @@ function elem(
|
|
|
111
111
|
if (INSECURE_URI.slice(0, 2) === '^/' &&
|
|
112
112
|
/\/\.\.?(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/)))) {
|
|
113
113
|
type = 'argument';
|
|
114
|
-
|
|
114
|
+
message = 'Dot-segments cannot be used in subresource paths';
|
|
115
115
|
break;
|
|
116
116
|
}
|
|
117
117
|
return html('a',
|
|
@@ -140,7 +140,7 @@ function elem(
|
|
|
140
140
|
return html('a', { href: uri.source }, content);
|
|
141
141
|
}
|
|
142
142
|
type = 'content';
|
|
143
|
-
|
|
143
|
+
message = 'Invalid phone number';
|
|
144
144
|
break;
|
|
145
145
|
}
|
|
146
146
|
return html('a',
|
|
@@ -148,7 +148,7 @@ function elem(
|
|
|
148
148
|
class: 'invalid',
|
|
149
149
|
'data-invalid-syntax': 'link',
|
|
150
150
|
'data-invalid-type': type ??= 'argument',
|
|
151
|
-
'data-invalid-
|
|
151
|
+
'data-invalid-message': message ??= 'Invalid protocol',
|
|
152
152
|
},
|
|
153
153
|
content.length === 0
|
|
154
154
|
? INSECURE_URI
|
|
@@ -9,7 +9,7 @@ import { unshift } from 'spica/array';
|
|
|
9
9
|
export const mark: MarkParser = lazy(() => creator(surround(
|
|
10
10
|
str('=='),
|
|
11
11
|
startTight(some(union([
|
|
12
|
-
some(inline, blank('',
|
|
12
|
+
some(inline, blank('', '==')),
|
|
13
13
|
open(some(inline, '='), inline),
|
|
14
14
|
]))),
|
|
15
15
|
str('=='), false,
|
|
@@ -29,7 +29,7 @@ export const math: MathParser = lazy(() => creator(validate('$', rewrite(
|
|
|
29
29
|
translate: 'no',
|
|
30
30
|
'data-invalid-syntax': 'math',
|
|
31
31
|
'data-invalid-type': 'content',
|
|
32
|
-
'data-invalid-
|
|
32
|
+
'data-invalid-message': `"${source.match(disallowedCommand)![0]}" command is disallowed`,
|
|
33
33
|
},
|
|
34
34
|
source)
|
|
35
35
|
], '']))));
|
|
@@ -81,7 +81,7 @@ function sanitize(target: HTMLElement, uri: ReadonlyURL, alt: string): boolean {
|
|
|
81
81
|
class: void target.classList.add('invalid'),
|
|
82
82
|
'data-invalid-syntax': 'media',
|
|
83
83
|
'data-invalid-type': 'argument',
|
|
84
|
-
'data-invalid-
|
|
84
|
+
'data-invalid-message': 'Dot-segments cannot be used in media paths; use subresource paths instead',
|
|
85
85
|
});
|
|
86
86
|
return false;
|
|
87
87
|
}
|
|
@@ -91,7 +91,7 @@ function sanitize(target: HTMLElement, uri: ReadonlyURL, alt: string): boolean {
|
|
|
91
91
|
class: void target.classList.add('invalid'),
|
|
92
92
|
'data-invalid-syntax': 'media',
|
|
93
93
|
'data-invalid-type': 'argument',
|
|
94
|
-
'data-invalid-
|
|
94
|
+
'data-invalid-message': 'Invalid protocol',
|
|
95
95
|
});
|
|
96
96
|
return false;
|
|
97
97
|
}
|
|
@@ -100,7 +100,7 @@ function sanitize(target: HTMLElement, uri: ReadonlyURL, alt: string): boolean {
|
|
|
100
100
|
class: void target.classList.add('invalid'),
|
|
101
101
|
'data-invalid-syntax': 'media',
|
|
102
102
|
'data-invalid-type': 'content',
|
|
103
|
-
'data-invalid-
|
|
103
|
+
'data-invalid-message': `Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)![0]}"`,
|
|
104
104
|
alt: target.getAttribute('alt')?.replace(/\0/g, ''),
|
|
105
105
|
});
|
|
106
106
|
return false;
|
|
@@ -46,7 +46,7 @@ function attributes(ns: (string | HTMLElement)[]): Record<string, string | undef
|
|
|
46
46
|
class: 'invalid',
|
|
47
47
|
'data-invalid-syntax': 'reference',
|
|
48
48
|
'data-invalid-type': 'syntax',
|
|
49
|
-
'data-invalid-
|
|
49
|
+
'data-invalid-message': 'Invalid abbr',
|
|
50
50
|
}
|
|
51
51
|
: { class: 'reference' };
|
|
52
52
|
}
|
|
@@ -83,13 +83,13 @@ function attributes(texts: string[], rubies: string[]): Record<string, string> {
|
|
|
83
83
|
let attrs: Record<string, string> | undefined;
|
|
84
84
|
for (const ss of [texts, rubies]) {
|
|
85
85
|
for (let i = 0; i < ss.length; ++i) {
|
|
86
|
-
if (
|
|
86
|
+
if (ss[i].indexOf('\0') === -1) continue;
|
|
87
87
|
ss[i] = ss[i].replace(/\0/g, '');
|
|
88
88
|
attrs ??= {
|
|
89
89
|
class: 'invalid',
|
|
90
90
|
'data-invalid-syntax': 'ruby',
|
|
91
91
|
'data-invalid-type': ss === texts ? 'content' : 'argument',
|
|
92
|
-
'data-invalid-
|
|
92
|
+
'data-invalid-message': 'Invalid HTML entity',
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -9,7 +9,7 @@ import { unshift } from 'spica/array';
|
|
|
9
9
|
export const strong: StrongParser = lazy(() => creator(surround(
|
|
10
10
|
str('**'),
|
|
11
11
|
startTight(some(union([
|
|
12
|
-
some(inline, blank('',
|
|
12
|
+
some(inline, blank('', '**')),
|
|
13
13
|
open(some(inline, '*'), inline),
|
|
14
14
|
])), '*'),
|
|
15
15
|
str('**'), false,
|
package/src/parser/inline.ts
CHANGED
|
@@ -75,5 +75,7 @@ export const inline: InlineParser = union([
|
|
|
75
75
|
text
|
|
76
76
|
]);
|
|
77
77
|
|
|
78
|
+
export { indexee } from './inline/extension/indexee';
|
|
79
|
+
export { indexer } from './inline/extension/indexer';
|
|
78
80
|
export { media } from './inline/media';
|
|
79
81
|
export { shortmedia } from './inline/shortmedia';
|