securemark 0.243.0 → 0.244.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.
@@ -26,14 +26,17 @@ export const segment_: TableParser.SegmentParser = block(validate('~~~',
26
26
  export const table: TableParser = block(validate('~~~', recover(fmap(
27
27
  fence(opener, 10000),
28
28
  // Bug: Type mismatch between outer and inner.
29
- ([body, closer, opener, delim, param]: string[], _, context) => {
30
- if (!closer || param.trimStart()) return [html('pre', {
29
+ ([body, overflow, closer, opener, delim, param]: string[], _, context) => {
30
+ if (!closer || overflow || param.trimStart()) return [html('pre', {
31
31
  class: 'invalid',
32
32
  translate: 'no',
33
33
  'data-invalid-syntax': 'table',
34
- 'data-invalid-type': !closer ? 'fence' : 'argument',
35
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid argument',
36
- }, `${opener}${body}${closer}`)];
34
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
35
+ 'data-invalid-message':
36
+ !closer ? `Missing the closing delimiter "${delim}"` :
37
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
38
+ 'Invalid argument',
39
+ }, `${opener}${body}${overflow || closer}`)];
37
40
  return eval(parser(body, context)) ?? [html('table')];
38
41
  }),
39
42
  (source, _, reason) =>
@@ -19,10 +19,12 @@ describe('Unit: parser/block/mathblock', () => {
19
19
  assert.deepStrictEqual(inspect(parser('$$ $$\n$$')), undefined);
20
20
  assert.deepStrictEqual(inspect(parser('$$lang\n$$')), [['<pre class="invalid" translate="no">$$lang\n$$</pre>'], '']);
21
21
  assert.deepStrictEqual(inspect(parser('$$ param\n$$')), [['<pre class="invalid" translate="no">$$ param\n$$</pre>'], '']);
22
+ assert.deepStrictEqual(inspect(parser('$$\n$$\n$$')), [['<pre class="invalid" translate="no">$$\n$$\n$$</pre>'], '']);
23
+ assert.deepStrictEqual(inspect(parser('$$\n$$$')), [['<pre class="invalid" translate="no">$$\n$$$</pre>'], '']);
22
24
  assert.deepStrictEqual(inspect(parser('$$$\n$$')), [['<pre class="invalid" translate="no">$$$\n$$</pre>'], '']);
23
25
  assert.deepStrictEqual(inspect(parser('$$$\n$$$')), [['<pre class="invalid" translate="no">$$$\n$$$</pre>'], '']);
24
26
  assert.deepStrictEqual(inspect(parser(' $$\n$$')), undefined);
25
- assert.deepStrictEqual(inspect(parser(`$$\n0${'\n'.repeat(101)}$$`), '>'), [['<pre class="invalid" translate="no">'], '']);
27
+ assert.deepStrictEqual(inspect(parser(`$$\n0${'\n'.repeat(301)}$$`), '>'), [['<pre class="invalid" translate="no">'], '']);
26
28
  });
27
29
 
28
30
  it('basic', () => {
@@ -34,12 +36,10 @@ describe('Unit: parser/block/mathblock', () => {
34
36
  assert.deepStrictEqual(inspect(parser('$$\n\\\n$$')), [['<div class="math" translate="no">$$\n\\\n$$</div>'], '']);
35
37
  assert.deepStrictEqual(inspect(parser('$$\n$\n$$')), [['<div class="math" translate="no">$$\n$\n$$</div>'], '']);
36
38
  assert.deepStrictEqual(inspect(parser('$$\n$\n\n$$')), [['<div class="math" translate="no">$$\n$\n\n$$</div>'], '']);
37
- assert.deepStrictEqual(inspect(parser('$$\n$$\n$$')), [['<div class="math" translate="no">$$\n$$\n$$</div>'], '']);
38
39
  assert.deepStrictEqual(inspect(parser('$$\n$$\n\n$$')), [['<div class="math" translate="no">$$\n$$</div>'], '\n$$']);
39
40
  assert.deepStrictEqual(inspect(parser('$$\n$$$\n$$')), [['<div class="math" translate="no">$$\n$$$\n$$</div>'], '']);
40
41
  assert.deepStrictEqual(inspect(parser('$$\n$$$\n\n$$')), [['<div class="math" translate="no">$$\n$$$\n\n$$</div>'], '']);
41
- assert.deepStrictEqual(inspect(parser('$$\n$$\n$$')), [['<div class="math" translate="no">$$\n$$\n$$</div>'], '']);
42
- assert.deepStrictEqual(inspect(parser(`$$\n0${'\n'.repeat(100)}$$`), '>'), [['<div class="math" translate="no">'], '']);
42
+ assert.deepStrictEqual(inspect(parser(`$$\n0${'\n'.repeat(300)}$$`), '>'), [['<div class="math" translate="no">'], '']);
43
43
  });
44
44
 
45
45
  });
@@ -6,23 +6,26 @@ import { html } from 'typed-dom/dom';
6
6
  const opener = /^(\${2,})(?!\$)([^\n]*)(?:$|\n)/;
7
7
 
8
8
  export const segment: MathBlockParser.SegmentParser = block(validate('$$',
9
- clear(fence(opener, 100))));
9
+ clear(fence(opener, 300))));
10
10
 
11
11
  export const segment_: MathBlockParser.SegmentParser = block(validate('$$',
12
- clear(fence(opener, 100, false))), false);
12
+ clear(fence(opener, 300, false))), false);
13
13
 
14
14
  export const mathblock: MathBlockParser = block(validate('$$', fmap(
15
- fence(opener, 100),
15
+ fence(opener, 300),
16
16
  // Bug: Type mismatch between outer and inner.
17
- ([body, closer, opener, delim, param]: string[], _, { caches: { math: cache = undefined } = {} }) => [
18
- delim.length === 2 && closer && param.trimStart() === ''
17
+ ([body, overflow, closer, opener, delim, param]: string[], _, { caches: { math: cache = undefined } = {} }) => [
18
+ delim.length === 2 && closer && !overflow && param.trimStart() === ''
19
19
  ? cache?.get(`${delim}\n${body}${delim}`)?.cloneNode(true) as HTMLDivElement ||
20
20
  html('div', { class: 'math', translate: 'no' }, `${delim}\n${body}${delim}`)
21
21
  : html('pre', {
22
22
  class: 'invalid',
23
23
  translate: 'no',
24
24
  'data-invalid-syntax': 'mathblock',
25
- 'data-invalid-type': delim.length > 2 ? 'syntax' : !closer ? 'fence' : 'argument',
26
- 'data-invalid-message': delim.length > 2 ? 'Invalid syntax' : !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid argument',
27
- }, `${opener}${body}${closer}`),
25
+ 'data-invalid-type': delim.length > 2 ? 'syntax' : !closer || overflow ? 'fence' : 'argument',
26
+ 'data-invalid-message': delim.length > 2 ? 'Invalid syntax' :
27
+ !closer ? `Missing the closing delimiter "${delim}"` :
28
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
29
+ 'Invalid argument',
30
+ }, `${opener}${body}${overflow || closer}`),
28
31
  ])));
@@ -29,9 +29,9 @@ const row = <P extends CellParser | AlignParser>(parser: P, optional: boolean):
29
29
  rewrite(contentline, source => [[
30
30
  html('tr', {
31
31
  class: 'invalid',
32
- 'data-invalid-syntax': 'tablerow',
32
+ 'data-invalid-syntax': 'table-row',
33
33
  'data-invalid-type': 'syntax',
34
- 'data-invalid-message': 'Invalid table row',
34
+ 'data-invalid-message': 'Missing the start symbol of the table row',
35
35
  }, [html('td', source.replace('\n', ''))])
36
36
  ], ''])));
37
37
 
@@ -93,22 +93,29 @@ describe('Unit: parser/inline/html', () => {
93
93
  assert.deepStrictEqual(inspect(parser('<small __proto__>a</small>')), undefined);
94
94
  assert.deepStrictEqual(inspect(parser('<small constructor>a</small>')), [['<span class="invalid">&lt;small constructor&gt;a&lt;/small&gt;</span>'], '']);
95
95
  assert.deepStrictEqual(inspect(parser('<small toString>a</small>')), undefined);
96
+ assert.deepStrictEqual(inspect(parser('<small X>a</small>')), undefined);
97
+ assert.deepStrictEqual(inspect(parser('<small x>a</small>')), [['<span class="invalid">&lt;small x&gt;a&lt;/small&gt;</span>'], '']);
96
98
  assert.deepStrictEqual(inspect(parser('<bdo>a</bdo>')), [['<span class="invalid">&lt;bdo&gt;a&lt;/bdo&gt;</span>'], '']);
97
99
  assert.deepStrictEqual(inspect(parser('<bdo >a</bdo>')), [['<span class="invalid">&lt;bdo &gt;a&lt;/bdo&gt;</span>'], '']);
98
100
  assert.deepStrictEqual(inspect(parser('<bdo __proto__>a</bdo>')), undefined);
99
101
  assert.deepStrictEqual(inspect(parser('<bdo constructor>a</bdo>')), [['<span class="invalid">&lt;bdo constructor&gt;a&lt;/bdo&gt;</span>'], '']);
100
102
  assert.deepStrictEqual(inspect(parser('<bdo toString>a</bdo>')), undefined);
103
+ assert.deepStrictEqual(inspect(parser('<bdo X>a</bdo>')), undefined);
104
+ assert.deepStrictEqual(inspect(parser('<bdo x>a</bdo>')), [['<span class="invalid">&lt;bdo x&gt;a&lt;/bdo&gt;</span>'], '']);
101
105
  assert.deepStrictEqual(inspect(parser('<bdo dir>a</bdo>')), [['<span class="invalid">&lt;bdo dir&gt;a&lt;/bdo&gt;</span>'], '']);
102
106
  assert.deepStrictEqual(inspect(parser('<bdo dir=>a</bdo>')), undefined);
103
107
  assert.deepStrictEqual(inspect(parser('<bdo dir=rtl>a</bdo>')), undefined);
104
108
  assert.deepStrictEqual(inspect(parser('<bdo dir=">a</bdo>')), undefined);
105
109
  assert.deepStrictEqual(inspect(parser('<bdo dir="">a</bdo>')), [['<span class="invalid">&lt;bdo dir=""&gt;a&lt;/bdo&gt;</span>'], '']);
106
110
  assert.deepStrictEqual(inspect(parser('<bdo dir="rtl" dir="rtl">a</bdo>')), [['<span class="invalid">&lt;bdo dir="rtl" dir="rtl"&gt;a&lt;/bdo&gt;</span>'], '']);
111
+ assert.deepStrictEqual(inspect(parser('<bdo diR="rtl">a</bdo>')), undefined);
107
112
  assert.deepStrictEqual(inspect(parser('<bdo dir="rtl">a</bdo>')), [['<bdo dir="rtl">a</bdo>'], '']);
108
113
  assert.deepStrictEqual(inspect(parser('<bdo dir="rtl" >a</bdo>')), [['<bdo dir="rtl">a</bdo>'], '']);
109
114
  assert.deepStrictEqual(inspect(parser('<bdo dir="rtl" >a</bdo>')), [['<bdo dir="rtl">a</bdo>'], '']);
110
115
  assert.deepStrictEqual(inspect(parser('<bdo dir="rtl">a</bdo>')), [['<bdo dir="rtl">a</bdo>'], '']);
111
116
  assert.deepStrictEqual(inspect(parser('<wbr constructor>')), [['<wbr class="invalid">'], '']);
117
+ assert.deepStrictEqual(inspect(parser('<wbr X>')), undefined);
118
+ assert.deepStrictEqual(inspect(parser('<wbr x>')), [['<wbr class="invalid">'], '']);
112
119
  });
113
120
 
114
121
  });
@@ -1,5 +1,5 @@
1
1
  import { undefined } from 'spica/global';
2
- import { isFrozen, ObjectEntries, ObjectFreeze, ObjectSetPrototypeOf, ObjectValues } from 'spica/alias';
2
+ import { isFrozen, ObjectEntries } from 'spica/alias';
3
3
  import { MarkdownParser } from '../../../markdown';
4
4
  import { HTMLParser } from '../inline';
5
5
  import { union, some, validate, context, creator, surround, open, match, lazy } from '../../combinator';
@@ -11,14 +11,14 @@ import { memoize } from 'spica/memoize';
11
11
  import { Cache } from 'spica/cache';
12
12
  import { unshift, push, splice, join } from 'spica/array';
13
13
 
14
- const tags = ObjectFreeze(['sup', 'sub', 'small', 'bdo', 'bdi']);
14
+ const tags = Object.freeze(['wbr', 'sup', 'sub', 'small', 'bdo', 'bdi']);
15
15
  const attrspec = {
16
16
  bdo: {
17
- dir: ObjectFreeze(['ltr', 'rtl'] as const),
17
+ dir: Object.freeze(['ltr', 'rtl'] as const),
18
18
  },
19
19
  } as const;
20
- ObjectSetPrototypeOf(attrspec, null);
21
- ObjectValues(attrspec).forEach(o => ObjectSetPrototypeOf(o, null));
20
+ Object.setPrototypeOf(attrspec, null);
21
+ Object.values(attrspec).forEach(o => Object.setPrototypeOf(o, null));
22
22
 
23
23
  export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-z]+(?=[^\S\n]|>)/, union([
24
24
  match(
@@ -29,7 +29,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
29
29
  `<${tag}`, some(union([attribute])), /^\s*>/, true,
30
30
  ([, bs = []], rest) =>
31
31
  [[h(tag as 'span', attributes('html', [], attrspec[tag], bs))], rest]),
32
- ([, tag]) => tag)),
32
+ ([, tag]) => tags.indexOf(tag), [])),
33
33
  match(
34
34
  /^(?=<(sup|sub|small)(?=[^\S\n]|>))/,
35
35
  memoize(
@@ -69,7 +69,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
69
69
  str(`</${tag}>`), false,
70
70
  ([as, bs, cs], rest, context) =>
71
71
  [[elem(tag, as, defrag(bs), cs, context)], rest])),
72
- ([, tag]) => tag)),
72
+ ([, tag]) => tags.indexOf(tag), [])),
73
73
  match(
74
74
  /^(?=<(bdo|bdi)(?=[^\S\n]|>))/,
75
75
  memoize(
@@ -82,11 +82,11 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
82
82
  open(/^\n?/, some(inline, '</'), true),
83
83
  ]), `</${tag}>`), `</${tag}>`),
84
84
  str(`</${tag}>`), false,
85
- ([as, bs, cs], rest) =>
86
- [[elem(tag, as, defrag(bs), cs, {})], rest],
85
+ ([as, bs, cs], rest, context) =>
86
+ [[elem(tag, as, defrag(bs), cs, context)], rest],
87
87
  ([as, bs], rest) =>
88
88
  as.length === 1 ? [unshift(as, bs), rest] : undefined)),
89
- ([, tag]) => tag)),
89
+ ([, tag]) => tags.indexOf(tag), [])),
90
90
  match(
91
91
  /^(?=<([a-z]+)(?=[^\S\n]|>))/,
92
92
  memoize(
@@ -99,12 +99,12 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
99
99
  open(/^\n?/, some(inline, '</'), true),
100
100
  ]), `</${tag}>`), `</${tag}>`),
101
101
  str(`</${tag}>`), false,
102
- ([as, bs, cs], rest) =>
103
- [[elem(tag, as, defrag(bs), cs, {})], rest],
102
+ ([as, bs, cs], rest, context) =>
103
+ [[elem(tag, as, defrag(bs), cs, context)], rest],
104
104
  ([as, bs], rest) =>
105
105
  as.length === 1 ? [unshift(as, bs), rest] : undefined)),
106
106
  ([, tag]) => tag,
107
- new Cache(1000))),
107
+ new Cache(10000))),
108
108
  ])))));
109
109
 
110
110
  export const attribute: HTMLParser.TagParser.AttributeParser = union([
@@ -133,12 +133,11 @@ function elem(tag: string, as: string[], bs: (HTMLElement | string)[], cs: strin
133
133
  }
134
134
  break;
135
135
  }
136
- let attrs: Record<string, string | undefined> | undefined;
136
+ const attrs = attributes('html', [], attrspec[tag], as.slice(1, -1));
137
137
  switch (true) {
138
- case 'data-invalid-syntax' in (attrs = attributes('html', [], attrspec[tag], as.slice(1, -1) as string[])):
138
+ case 'data-invalid-syntax' in attrs:
139
139
  return invalid('attribute', 'Invalid HTML attribute', as, bs, cs);
140
140
  default:
141
- assert(attrs);
142
141
  return h(tag as 'span', attrs, bs);
143
142
  }
144
143
  }
@@ -158,7 +157,7 @@ const requiredAttributes = memoize(
158
157
 
159
158
  export function attributes(
160
159
  syntax: string,
161
- classes: string[],
160
+ classes: readonly string[],
162
161
  spec: Readonly<Record<string, readonly (string | undefined)[] | undefined>> | undefined,
163
162
  params: string[],
164
163
  ): Record<string, string | undefined> {
@@ -183,8 +182,7 @@ export function attributes(
183
182
  }
184
183
  invalid ||= !!spec && !requiredAttributes(spec).every(name => name in attrs);
185
184
  if (invalid) {
186
- !classes.includes('invalid') && classes.push('invalid');
187
- attrs['class'] = join(classes, ' ');
185
+ attrs['class'] = join(classes.includes('invalid') ? classes : unshift(classes, ['invalid']), ' ');
188
186
  attrs['data-invalid-syntax'] = syntax;
189
187
  attrs['data-invalid-type'] = 'argument';
190
188
  attrs['data-invalid-message'] = 'Invalid argument';
@@ -1,5 +1,4 @@
1
- import { location, encodeURI, decodeURI, Location } from 'spica/global';
2
- import { ObjectSetPrototypeOf } from 'spica/alias';
1
+ import { undefined, location, encodeURI, decodeURI, Location } from 'spica/global';
3
2
  import { LinkParser } from '../inline';
4
3
  import { eval } from '../../combinator/data/parser';
5
4
  import { union, inits, tails, some, validate, guard, context, creator, surround, open, dup, reverse, lazy, fmap, bind } from '../../combinator';
@@ -14,7 +13,7 @@ import { ReadonlyURL } from 'spica/url';
14
13
  const optspec = {
15
14
  rel: ['nofollow'],
16
15
  } as const;
17
- ObjectSetPrototypeOf(optspec, null);
16
+ Object.setPrototypeOf(optspec, null);
18
17
 
19
18
  export const link: LinkParser = lazy(() => creator(10, validate(['[', '{'], '}', '\n', bind(
20
19
  guard(context => context.syntax?.inline?.link ?? true,
@@ -1,5 +1,4 @@
1
1
  import { undefined, location } from 'spica/global';
2
- import { ObjectSetPrototypeOf } from 'spica/alias';
3
2
  import { MediaParser } from '../inline';
4
3
  import { union, inits, tails, some, validate, verify, guard, creator, surround, open, dup, lazy, fmap, bind } from '../../combinator';
5
4
  import { link, uri, option as linkoption, resolve } from './link';
@@ -16,7 +15,7 @@ const optspec = {
16
15
  'aspect-ratio': [],
17
16
  rel: undefined,
18
17
  } as const;
19
- ObjectSetPrototypeOf(optspec, null);
18
+ Object.setPrototypeOf(optspec, null);
20
19
 
21
20
  export const media: MediaParser = lazy(() => creator(10, validate(['![', '!{'], '}', '\n', bind(verify(fmap(open(
22
21
  '!',
@@ -1,6 +1,6 @@
1
- import { define } from 'typed-dom/dom';
2
- import { Collection } from 'spica/collection';
3
1
  import { ObjectFromEntries } from 'spica/alias';
2
+ import { Collection } from 'spica/collection';
3
+ import { define } from 'typed-dom/dom';
4
4
 
5
5
  export function image(source: HTMLImageElement, url: URL, cache?: Collection<string, HTMLElement>): HTMLImageElement {
6
6
  if (cache?.has(url.href)) return define(
@@ -1,5 +1,5 @@
1
- import { html } from 'typed-dom/dom';
2
1
  import { ObjectFromEntries } from 'spica/alias';
2
+ import { html } from 'typed-dom/dom';
3
3
 
4
4
  const extensions = [
5
5
  '.webm',
@@ -1,3 +1,4 @@
1
+ import { undefined } from 'spica/global';
1
2
  import { html } from 'typed-dom/dom';
2
3
 
3
4
  export function youtube(source: HTMLImageElement, url: URL): HTMLElement | undefined {