securemark 0.243.1 → 0.243.2

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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.243.2
4
+
5
+ - Refactoring.
6
+
3
7
  ## 0.243.1
4
8
 
5
9
  - Refactoring.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.243.1 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.243.2 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) {
@@ -3782,7 +3782,7 @@ require = function () {
3782
3782
  ])
3783
3783
  ])
3784
3784
  ]), closer), ([, fence]) => fence.length, [])));
3785
- exports.figure = (0, combinator_1.block)((0, combinator_1.fallback)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.fallback)((0, combinator_1.fmap)((0, combinator_1.convert)(source => source.slice(source.match(/^~+(?:figure[^\S\n]+)?/)[0].length, source.trimEnd().lastIndexOf('\n')), (0, combinator_1.sequence)([
3785
+ exports.figure = (0, combinator_1.block)((0, combinator_1.fallback)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.fmap)((0, combinator_1.convert)(source => source.slice(source.match(/^~+(?:figure[^\S\n]+)?/)[0].length, source.trimEnd().lastIndexOf('\n')), (0, combinator_1.sequence)([
3786
3786
  (0, combinator_1.line)((0, combinator_1.sequence)([
3787
3787
  label_1.label,
3788
3788
  (0, source_1.str)(/^(?=\s).*\n/)
@@ -3808,27 +3808,7 @@ require = function () {
3808
3808
  ])), ([label, param, content, ...caption]) => [(0, dom_1.html)('figure', attributes(label.getAttribute('data-label'), param, content, caption), [
3809
3809
  (0, dom_1.html)('figcaption', (0, array_1.unshift)([(0, dom_1.html)('span', { class: 'figindex' })], (0, dom_1.defrag)(caption))),
3810
3810
  (0, dom_1.html)('div', [content])
3811
- ])]), (source, context) => {
3812
- var _a, _b;
3813
- return [
3814
- [(0, dom_1.html)('pre', {
3815
- class: 'invalid',
3816
- translate: 'no',
3817
- 'data-invalid-syntax': 'figure',
3818
- ...!(0, label_1.segment)((_b = (_a = source.match(/^~+(?:figure[^\S\n]+)?(\[?\$\S+)/)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : '', context) && {
3819
- 'data-invalid-type': 'label',
3820
- 'data-invalid-message': 'Invalid label'
3821
- } || /^~+(?:figure[^\S\n]+)?(\[?\$\S+)[^\S\n]+\S/.test(source) && {
3822
- 'data-invalid-type': 'argument',
3823
- 'data-invalid-message': 'Invalid argument'
3824
- } || {
3825
- 'data-invalid-type': 'content',
3826
- 'data-invalid-message': 'Invalid content'
3827
- }
3828
- }, source)],
3829
- ''
3830
- ];
3831
- })), (0, combinator_1.fmap)((0, combinator_1.fence)(/^(~{3,})(?:figure|\[?\$\S*)(?!\S)[^\n]*(?:$|\n)/, 300), ([body, closer, opener, delim], _, context) => {
3811
+ ])])), (0, combinator_1.fmap)((0, combinator_1.fence)(/^(~{3,})(?:figure|\[?\$\S*)(?!\S)[^\n]*(?:$|\n)/, 300), ([body, closer, opener, delim], _, context) => {
3832
3812
  var _a, _b;
3833
3813
  return [(0, dom_1.html)('pre', {
3834
3814
  class: 'invalid',
@@ -5991,7 +5971,8 @@ require = function () {
5991
5971
  const memoize_1 = _dereq_('spica/memoize');
5992
5972
  const cache_1 = _dereq_('spica/cache');
5993
5973
  const array_1 = _dereq_('spica/array');
5994
- const tags = (0, alias_1.ObjectFreeze)([
5974
+ const tags = Object.freeze([
5975
+ 'wbr',
5995
5976
  'sup',
5996
5977
  'sub',
5997
5978
  'small',
@@ -6000,19 +5981,19 @@ require = function () {
6000
5981
  ]);
6001
5982
  const attrspec = {
6002
5983
  bdo: {
6003
- dir: (0, alias_1.ObjectFreeze)([
5984
+ dir: Object.freeze([
6004
5985
  'ltr',
6005
5986
  'rtl'
6006
5987
  ])
6007
5988
  }
6008
5989
  };
6009
- (0, alias_1.ObjectSetPrototypeOf)(attrspec, null);
6010
- (0, alias_1.ObjectValues)(attrspec).forEach(o => (0, alias_1.ObjectSetPrototypeOf)(o, null));
5990
+ Object.setPrototypeOf(attrspec, null);
5991
+ Object.values(attrspec).forEach(o => Object.setPrototypeOf(o, null));
6011
5992
  exports.html = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('<', (0, combinator_1.validate)(/^<[a-z]+(?=[^\S\n]|>)/, (0, combinator_1.union)([
6012
5993
  (0, combinator_1.match)(/^(?=<(wbr)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)(`<${ tag }`, (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), /^\s*>/, true, ([, bs = []], rest) => [
6013
5994
  [(0, dom_1.html)(tag, attributes('html', [], attrspec[tag], bs))],
6014
5995
  rest
6015
- ]), ([, tag]) => tag)),
5996
+ ]), ([, tag]) => tags.indexOf(tag), [])),
6016
5997
  (0, combinator_1.match)(/^(?=<(sup|sub|small)(?=[^\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)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.context)((() => {
6017
5998
  switch (tag) {
6018
5999
  case 'sup':
@@ -6041,27 +6022,27 @@ require = function () {
6041
6022
  ]), `</${ tag }>`)), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest, context) => [
6042
6023
  [elem(tag, as, (0, dom_1.defrag)(bs), cs, context)],
6043
6024
  rest
6044
- ])), ([, tag]) => tag)),
6025
+ ])), ([, tag]) => tags.indexOf(tag), [])),
6045
6026
  (0, combinator_1.match)(/^(?=<(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)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([
6046
6027
  (0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n?/, `</${ tag }>`)),
6047
6028
  (0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, '</'), true)
6048
- ]), `</${ tag }>`), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest) => [
6049
- [elem(tag, as, (0, dom_1.defrag)(bs), cs, {})],
6029
+ ]), `</${ tag }>`), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest, context) => [
6030
+ [elem(tag, as, (0, dom_1.defrag)(bs), cs, context)],
6050
6031
  rest
6051
6032
  ], ([as, bs], rest) => as.length === 1 ? [
6052
6033
  (0, array_1.unshift)(as, bs),
6053
6034
  rest
6054
- ] : global_1.undefined)), ([, tag]) => tag)),
6035
+ ] : global_1.undefined)), ([, tag]) => tags.indexOf(tag), [])),
6055
6036
  (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)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([
6056
6037
  (0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n?/, `</${ tag }>`)),
6057
6038
  (0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, '</'), true)
6058
- ]), `</${ tag }>`), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest) => [
6059
- [elem(tag, as, (0, dom_1.defrag)(bs), cs, {})],
6039
+ ]), `</${ tag }>`), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest, context) => [
6040
+ [elem(tag, as, (0, dom_1.defrag)(bs), cs, context)],
6060
6041
  rest
6061
6042
  ], ([as, bs], rest) => as.length === 1 ? [
6062
6043
  (0, array_1.unshift)(as, bs),
6063
6044
  rest
6064
- ] : global_1.undefined)), ([, tag]) => tag, new cache_1.Cache(1000)))
6045
+ ] : global_1.undefined)), ([, tag]) => tag, new cache_1.Cache(10000)))
6065
6046
  ])))));
6066
6047
  exports.attribute = (0, combinator_1.union)([(0, source_1.str)(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|>)/)]);
6067
6048
  function elem(tag, as, bs, cs, context) {
@@ -6084,9 +6065,9 @@ require = function () {
6084
6065
  }
6085
6066
  break;
6086
6067
  }
6087
- let attrs;
6068
+ const attrs = attributes('html', [], attrspec[tag], as.slice(1, -1));
6088
6069
  switch (true) {
6089
- case 'data-invalid-syntax' in (attrs = attributes('html', [], attrspec[tag], as.slice(1, -1))):
6070
+ case 'data-invalid-syntax' in attrs:
6090
6071
  return invalid('attribute', 'Invalid HTML attribute', as, bs, cs);
6091
6072
  default:
6092
6073
  return (0, dom_1.html)(tag, attrs, bs);
@@ -6117,8 +6098,7 @@ require = function () {
6117
6098
  }
6118
6099
  invalid || (invalid = !!spec && !requiredAttributes(spec).every(name => name in attrs));
6119
6100
  if (invalid) {
6120
- !classes.includes('invalid') && classes.push('invalid');
6121
- attrs['class'] = (0, array_1.join)(classes, ' ');
6101
+ attrs['class'] = (0, array_1.join)(classes.includes('invalid') ? classes : (0, array_1.unshift)(classes, ['invalid']), ' ');
6122
6102
  attrs['data-invalid-syntax'] = syntax;
6123
6103
  attrs['data-invalid-type'] = 'argument';
6124
6104
  attrs['data-invalid-message'] = 'Invalid argument';
@@ -6214,7 +6194,6 @@ require = function () {
6214
6194
  Object.defineProperty(exports, '__esModule', { value: true });
6215
6195
  exports.resolve = exports.option = exports.uri = exports.link = void 0;
6216
6196
  const global_1 = _dereq_('spica/global');
6217
- const alias_1 = _dereq_('spica/alias');
6218
6197
  const parser_1 = _dereq_('../../combinator/data/parser');
6219
6198
  const combinator_1 = _dereq_('../../combinator');
6220
6199
  const inline_1 = _dereq_('../inline');
@@ -6225,7 +6204,7 @@ require = function () {
6225
6204
  const dom_1 = _dereq_('typed-dom/dom');
6226
6205
  const url_1 = _dereq_('spica/url');
6227
6206
  const optspec = { rel: ['nofollow'] };
6228
- (0, alias_1.ObjectSetPrototypeOf)(optspec, null);
6207
+ Object.setPrototypeOf(optspec, null);
6229
6208
  exports.link = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.validate)([
6230
6209
  '[',
6231
6210
  '{'
@@ -6345,7 +6324,6 @@ require = function () {
6345
6324
  '../source': 128,
6346
6325
  '../util': 134,
6347
6326
  './html': 111,
6348
- 'spica/alias': 5,
6349
6327
  'spica/global': 13,
6350
6328
  'spica/url': 21,
6351
6329
  'typed-dom/dom': 23
@@ -6430,7 +6408,6 @@ require = function () {
6430
6408
  Object.defineProperty(exports, '__esModule', { value: true });
6431
6409
  exports.media = void 0;
6432
6410
  const global_1 = _dereq_('spica/global');
6433
- const alias_1 = _dereq_('spica/alias');
6434
6411
  const combinator_1 = _dereq_('../../combinator');
6435
6412
  const link_1 = _dereq_('./link');
6436
6413
  const html_1 = _dereq_('./html');
@@ -6445,7 +6422,7 @@ require = function () {
6445
6422
  'aspect-ratio': [],
6446
6423
  rel: global_1.undefined
6447
6424
  };
6448
- (0, alias_1.ObjectSetPrototypeOf)(optspec, null);
6425
+ Object.setPrototypeOf(optspec, null);
6449
6426
  exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.validate)([
6450
6427
  '![',
6451
6428
  '!{'
@@ -6573,7 +6550,6 @@ require = function () {
6573
6550
  './html': 111,
6574
6551
  './htmlentity': 112,
6575
6552
  './link': 114,
6576
- 'spica/alias': 5,
6577
6553
  'spica/array': 6,
6578
6554
  'spica/global': 13,
6579
6555
  'spica/url': 21,
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.243.1",
3
+ "version": "0.243.2",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -1962,9 +1962,9 @@
1962
1962
  "dev": true
1963
1963
  },
1964
1964
  "caniuse-lite": {
1965
- "version": "1.0.30001332",
1966
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz",
1967
- "integrity": "sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw==",
1965
+ "version": "1.0.30001334",
1966
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001334.tgz",
1967
+ "integrity": "sha512-kbaCEBRRVSoeNs74sCuq92MJyGrMtjWVfhltoHUCW4t4pXFvGjUBrfo47weBRViHkiV3eBYyIsfl956NtHGazw==",
1968
1968
  "dev": true
1969
1969
  },
1970
1970
  "chalk": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.243.1",
3
+ "version": "0.243.2",
4
4
  "description": "Secure markdown renderer working on browsers for user input data.",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/falsandtru/securemark",
@@ -48,7 +48,7 @@ export const segment: FigureParser.SegmentParser = block(match(
48
48
  closer),
49
49
  ([, fence]) => fence.length, [])));
50
50
 
51
- export const figure: FigureParser = block(fallback(rewrite(segment, fallback(fmap(
51
+ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
52
52
  convert(source => source.slice(source.match(/^~+(?:figure[^\S\n]+)?/)![0].length, source.trimEnd().lastIndexOf('\n')),
53
53
  sequence([
54
54
  line(sequence([label, str(/^(?=\s).*\n/)])),
@@ -82,27 +82,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fallback(fma
82
82
  defrag(caption))),
83
83
  html('div', [content]),
84
84
  ])
85
- ]),
86
- (source, context) => [[
87
- html('pre', {
88
- class: 'invalid',
89
- translate: 'no',
90
- 'data-invalid-syntax': 'figure',
91
- ...
92
- !seg_label(source.match(/^~+(?:figure[^\S\n]+)?(\[?\$\S+)/)?.[1] ?? '', context) && {
93
- 'data-invalid-type': 'label',
94
- 'data-invalid-message': 'Invalid label',
95
- } ||
96
- /^~+(?:figure[^\S\n]+)?(\[?\$\S+)[^\S\n]+\S/.test(source) && {
97
- 'data-invalid-type': 'argument',
98
- 'data-invalid-message': 'Invalid argument',
99
- } ||
100
- {
101
- 'data-invalid-type': 'content',
102
- 'data-invalid-message': 'Invalid content',
103
- },
104
- }, source),
105
- ], ''])),
85
+ ])),
106
86
  fmap(
107
87
  fence(/^(~{3,})(?:figure|\[?\$\S*)(?!\S)[^\n]*(?:$|\n)/, 300),
108
88
  ([body, closer, opener, delim]: string[], _, context) => [
@@ -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
1
  import { location, encodeURI, decodeURI, Location } from 'spica/global';
2
- import { ObjectSetPrototypeOf } from 'spica/alias';
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
  '!',