securemark 0.254.1 → 0.254.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.254.2
4
+
5
+ - Refactoring.
6
+
3
7
  ## 0.254.1
4
8
 
5
9
  - Fix footnote processing.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.254.1 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.254.2 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
2
2
  (function webpackUniversalModuleDefinition(root, factory) {
3
3
  if(typeof exports === 'object' && typeof module === 'object')
4
4
  module.exports = factory(require("DOMPurify"), require("Prism"));
@@ -6219,7 +6219,7 @@ const attrspecs = {
6219
6219
  global_1.Object.setPrototypeOf(attrspecs, null);
6220
6220
  global_1.Object.values(attrspecs).forEach(o => global_1.Object.setPrototypeOf(o, null));
6221
6221
  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)([(0, combinator_1.focus)('<wbr>', () => [[(0, dom_1.html)('wbr')], '']), (0, combinator_1.focus)( // https://html.spec.whatwg.org/multipage/syntax.html#void-elements
6222
- /^<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[^\S\n]|>)/, source => [[source], '']), (0, combinator_1.match)(new RegExp(String.raw`^<(${TAGS.join('|')})(?=[^\S\n]|>)`), (0, memoize_1.memoize)(([, 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\n]*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, (0, util_1.blankWith)('\n', `</${tag}>`)), true)])), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, bs, cs)], rest]), ([, tag]) => TAGS.indexOf(tag), [])), (0, combinator_1.match)(/^<([a-z]+)(?=[^\S\n]|>)/, (0, memoize_1.memoize)(([, 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\n]*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, (0, util_1.blankWith)('\n', `</${tag}>`)), true)])), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, bs, cs)], rest]), ([, tag]) => tag, new cache_1.Cache(10000)))])))));
6222
+ /^<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[^\S\n]|>)/, source => [[source], '']), (0, combinator_1.match)(new RegExp(String.raw`^<(${TAGS.join('|')})(?=[^\S\n]|>)`), (0, memoize_1.memoize)(([, 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\n]*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, (0, util_1.blankWith)('\n', `</${tag}>`)), true)])), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, bs, cs)], rest]), ([, tag]) => TAGS.indexOf(tag), [])), (0, combinator_1.match)(new RegExp(String.raw`^<(?!${TAGS.join('|')}\b)([a-z]+)(?=[^\S\n]|>)`), (0, memoize_1.memoize)(([, 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\n]*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, (0, util_1.blankWith)('\n', `</${tag}>`)), true)])), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, bs, cs)], rest]), ([, tag]) => tag, new cache_1.Cache(10000)))])))));
6223
6223
  exports.attribute = (0, combinator_1.union)([(0, source_1.str)(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|>)/)]); // https://developer.mozilla.org/en-US/docs/Web/HTML/Element
6224
6224
  // [...document.querySelectorAll('tbody > tr > td:first-child')].map(el => el.textContent.slice(1, -1))
6225
6225
 
@@ -6588,6 +6588,12 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, c
6588
6588
  cache?.hasAttribute('alt') && cache?.setAttribute('alt', text);
6589
6589
  if (!sanitize(el, url, text)) return [[el], rest];
6590
6590
  (0, dom_1.define)(el, (0, html_1.attributes)('media', (0, array_1.push)([], el.classList), optspec, params));
6591
+
6592
+ // Awaiting the generic support for attr().
6593
+ if (el.hasAttribute('aspect-ratio')) {
6594
+ el.style.aspectRatio = el.getAttribute('aspect-ratio');
6595
+ }
6596
+
6591
6597
  if (context.syntax?.inline?.link === false || cache && cache.tagName !== 'IMG') return [[el], rest];
6592
6598
  return (0, combinator_1.fmap)(link_1.link, ([link]) => [(0, dom_1.define)(link, {
6593
6599
  target: '_blank'
@@ -7637,7 +7643,7 @@ const str_1 = __webpack_require__(2790);
7637
7643
 
7638
7644
  const dom_1 = __webpack_require__(3252);
7639
7645
 
7640
- exports.delimiter = /[\s\x00-\x7F]|\S#|[、。!?][^\S\n]*(?=\\\n)/;
7646
+ exports.delimiter = /[\s\x00-\x7F]|\S#|[()、。!?][^\S\n]*(?=\\\n)/;
7641
7647
  exports.nonWhitespace = /[\S\n]|$/;
7642
7648
  exports.nonAlphanumeric = /[^0-9A-Za-z]|\S#|$/;
7643
7649
  const repeat = (0, str_1.str)(/^(.)\1*/);
@@ -8378,6 +8384,7 @@ function video(source, url) {
8378
8384
  src: source.getAttribute('data-src'),
8379
8385
  'data-type': 'video',
8380
8386
  ...global_1.Object.fromEntries([...source.attributes].map(attr => [attr.name, attr.value])),
8387
+ style: source.hasAttribute('aspect-ratio') ? `aspect-ratio: ${source.getAttribute('aspect-ratio')};` : global_1.undefined,
8381
8388
  muted: '',
8382
8389
  controls: ''
8383
8390
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.254.1",
3
+ "version": "0.254.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",
@@ -27,7 +27,7 @@ describe('Unit: parser/api/bind', () => {
27
27
  return acc;
28
28
  }
29
29
 
30
- const cfgs = { footnotes: { annotations: html('ol'), references: html('ol') } };
30
+ const cfgs = { footnotes: { references: html('ol') } };
31
31
 
32
32
  it('huge input', () => {
33
33
  const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(10 * 1000 ** 2)}`);
@@ -168,62 +168,62 @@ describe('Unit: parser/api/bind', () => {
168
168
  const el = html('div');
169
169
  const chunk = frag();
170
170
  const update = bind(chunk, { ...cfgs, chunk: true }).parse;
171
- const iter = update([...Array(3)].map((_, i) => `((${i + 1}))`).join('\n\n'));
171
+ const iter = update([...Array(3)].map((_, i) => `[[${i + 1}]]`).join('\n\n'));
172
172
 
173
173
  inspect(iter, 2);
174
174
  el.appendChild(chunk);
175
175
  assert.deepStrictEqual(
176
176
  [...el.children].map(el => el.outerHTML),
177
177
  [
178
- html('p', [html('sup', { class: "annotation" }, [html('span', '1')]),]).outerHTML,
179
- html('p', [html('sup', { class: "annotation" }, [html('span', '2')]),]).outerHTML,
178
+ html('p', [html('sup', { class: "reference" }, [html('span', '1')]),]).outerHTML,
179
+ html('p', [html('sup', { class: "reference" }, [html('span', '2')]),]).outerHTML,
180
180
  ]);
181
181
  inspect(iter, 1);
182
182
  el.appendChild(chunk);
183
183
  assert.deepStrictEqual(
184
184
  [...el.children].map(el => el.outerHTML),
185
185
  [
186
- html('p', [html('sup', { class: "annotation" }, [html('span', '1')]),]).outerHTML,
187
- html('p', [html('sup', { class: "annotation" }, [html('span', '2')]),]).outerHTML,
188
- html('p', [html('sup', { class: "annotation" }, [html('span', '3')]),]).outerHTML,
186
+ html('p', [html('sup', { class: "reference" }, [html('span', '1')]),]).outerHTML,
187
+ html('p', [html('sup', { class: "reference" }, [html('span', '2')]),]).outerHTML,
188
+ html('p', [html('sup', { class: "reference" }, [html('span', '3')]),]).outerHTML,
189
189
  ]);
190
190
  inspect(iter);
191
191
  assert.deepStrictEqual(
192
192
  [...el.children].map(el => el.outerHTML),
193
193
  [
194
194
  html('p', [
195
- html('sup', { class: "annotation", id: "annotation:ref:1", title: "1" }, [
195
+ html('sup', { class: "reference", id: "reference:ref:1", title: "1" }, [
196
196
  html('span', { hidden: '' }, '1'),
197
- html('a', { href: "#annotation:def:1" }, '*1')
197
+ html('a', { href: "#reference:def:1" }, '[1]'),
198
198
  ]),
199
199
  ]).outerHTML,
200
200
  html('p', [
201
- html('sup', { class: "annotation", id: "annotation:ref:2", title: "2" }, [
201
+ html('sup', { class: "reference", id: "reference:ref:2", title: "2" }, [
202
202
  html('span', { hidden: '' }, '2'),
203
- html('a', { href: "#annotation:def:2" }, '*2')
203
+ html('a', { href: "#reference:def:2" }, '[2]'),
204
204
  ]),
205
205
  ]).outerHTML,
206
206
  html('p', [
207
- html('sup', { class: "annotation", id: "annotation:ref:3", title: "3" }, [
207
+ html('sup', { class: "reference", id: "reference:ref:3", title: "3" }, [
208
208
  html('span', { hidden: '' }, '3'),
209
- html('a', { href: "#annotation:def:3" }, '*3')
209
+ html('a', { href: "#reference:def:3" }, '[3]'),
210
210
  ]),
211
211
  ]).outerHTML,
212
212
  ]);
213
213
  assert.deepStrictEqual(
214
- cfgs.footnotes.annotations?.outerHTML,
214
+ cfgs.footnotes.references?.outerHTML,
215
215
  html('ol', [
216
- html('li', { id: 'annotation:def:1' }, [
216
+ html('li', { id: 'reference:def:1' }, [
217
217
  '1',
218
- html('sup', [html('a', { href: '#annotation:ref:1' }, '^1')])
218
+ html('sup', [html('a', { href: '#reference:ref:1' }, '^1')]),
219
219
  ]),
220
- html('li', { id: 'annotation:def:2' }, [
220
+ html('li', { id: 'reference:def:2' }, [
221
221
  '2',
222
- html('sup', [html('a', { href: '#annotation:ref:2' }, '^2')])
222
+ html('sup', [html('a', { href: '#reference:ref:2' }, '^2')]),
223
223
  ]),
224
- html('li', { id: 'annotation:def:3' }, [
224
+ html('li', { id: 'reference:def:3' }, [
225
225
  '3',
226
- html('sup', [html('a', { href: '#annotation:ref:3' }, '^3')])
226
+ html('sup', [html('a', { href: '#reference:ref:3' }, '^3')]),
227
227
  ]),
228
228
  ]).outerHTML);
229
229
  assert.throws(() => update('').next());
@@ -204,16 +204,14 @@ describe('Unit: parser/api/parse', () => {
204
204
  });
205
205
 
206
206
  it('footnote', () => {
207
- const footnotes = { annotations: html('ol'), references: html('ol') };
207
+ const footnotes = { references: html('ol') };
208
208
  assert.deepStrictEqual(
209
209
  [...parse('$-a\n$$\n$$\n\n(($-a[[b]][[c*d*]]))', { footnotes }).children].map(el => el.outerHTML),
210
210
  [
211
211
  '<figure data-type="math" data-label="$-a" data-group="$" data-number="1" id="label:$-a"><figcaption><span class="figindex">(1)</span><span class="figtext"></span></figcaption><div><div class="math" translate="no">$$\n$$</div></div></figure>',
212
212
  '<p><sup class="annotation" id="annotation:ref:1" title="(1)[1][2]"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" id="reference:ref:1" title="b"><span hidden="">b</span><a href="#reference:def:1">[1]</a></sup><sup class="reference" id="reference:ref:2" title="cd"><span hidden="">c<em>d</em></span><a href="#reference:def:2">[2]</a></sup></span><a href="#annotation:def:1">*1</a></sup></p>',
213
+ '<ol class="annotations"><li id="annotation:def:1" data-marker="*1"><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" id="reference:ref:1" title="b"><span hidden="">b</span><a href="#reference:def:1">[1]</a></sup><sup class="reference" id="reference:ref:2" title="cd"><span hidden="">c<em>d</em></span><a href="#reference:def:2">[2]</a></sup><sup><a href="#annotation:ref:1">^1</a></sup></li></ol>',
213
214
  ]);
214
- assert.deepStrictEqual(
215
- footnotes.annotations.outerHTML,
216
- '<ol><li id="annotation:def:1"><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" id="reference:ref:1" title="b"><span hidden="">b</span><a href="#reference:def:1">[1]</a></sup><sup class="reference" id="reference:ref:2" title="cd"><span hidden="">c<em>d</em></span><a href="#reference:def:2">[2]</a></sup><sup><a href="#annotation:ref:1">^1</a></sup></li></ol>');
217
215
  assert.deepStrictEqual(
218
216
  footnotes.references.outerHTML,
219
217
  '<ol><li id="reference:def:1">b<sup><a href="#reference:ref:1">^1</a></sup></li><li id="reference:def:2">c<em>d</em><sup><a href="#reference:ref:2">^2</a></sup></li></ol>');
@@ -46,7 +46,6 @@ describe('Unit: parser/inline/annotation', () => {
46
46
  assert.deepStrictEqual(inspect(parser('((@a))')), [['<sup class="annotation"><span><a href="/@a" class="account">@a</a></span></sup>'], '']);
47
47
  assert.deepStrictEqual(inspect(parser('((http://host))')), [['<sup class="annotation"><span><a href="http://host" target="_blank">http://host</a></span></sup>'], '']);
48
48
  assert.deepStrictEqual(inspect(parser('((![]{a}))')), [['<sup class="annotation"><span>!<a href="a">a</a></span></sup>'], '']);
49
- assert.deepStrictEqual(inspect(parser('((<a>))')), [['<sup class="annotation"><span>&lt;a&gt;</span></sup>'], '']);
50
49
  assert.deepStrictEqual(inspect(parser('(((a)))')), [['<sup class="annotation"><span>(a)</span></sup>'], '']);
51
50
  assert.deepStrictEqual(inspect(parser('((((a))))')), [['<sup class="annotation"><span><span class="paren">((a))</span></span></sup>'], '']);
52
51
  assert.deepStrictEqual(inspect(parser('(([[a]]))')), [['<sup class="annotation"><span><sup class="reference"><span>a</span></sup></span></sup>'], '']);
@@ -46,7 +46,6 @@ describe('Unit: parser/inline/emphasis', () => {
46
46
  assert.deepStrictEqual(inspect(parser('*a**b**c*')), [['<em>a<strong>b</strong>c</em>'], '']);
47
47
  assert.deepStrictEqual(inspect(parser('*a**b**c*d')), [['<em>a<strong>b</strong>c</em>'], 'd']);
48
48
  assert.deepStrictEqual(inspect(parser('*`a`*')), [['<em><code data-src="`a`">a</code></em>'], '']);
49
- assert.deepStrictEqual(inspect(parser('*<bdi>*')), [['<em>&lt;bdi&gt;</em>'], '']);
50
49
  assert.deepStrictEqual(inspect(parser('*(*a*)*')), [['<em><span class="paren">(<em>a</em>)</span></em>'], '']);
51
50
  assert.deepStrictEqual(inspect(parser('*(**a**)*')), [['<em><span class="paren">(<strong>a</strong>)</span></em>'], '']);
52
51
  });
@@ -40,7 +40,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
40
40
  [[elem(tag, as, bs, cs)], rest]),
41
41
  ([, tag]) => TAGS.indexOf(tag), [])),
42
42
  match(
43
- /^<([a-z]+)(?=[^\S\n]|>)/,
43
+ new RegExp(String.raw`^<(?!${TAGS.join('|')}\b)([a-z]+)(?=[^\S\n]|>)`),
44
44
  memoize(
45
45
  ([, tag]) =>
46
46
  surround<HTMLParser.TagParser, string>(surround(
@@ -106,9 +106,9 @@ describe('Unit: parser/inline/media', () => {
106
106
  assert.deepStrictEqual(inspect(parser('![]{/ nofollow}')), [['<a href="/" rel="nofollow" target="_blank"><img class="media" data-src="/" alt=""></a>'], '']);
107
107
  assert.deepStrictEqual(inspect(parser('![]{/ width="4" height="3"}')), [['<a href="/" target="_blank"><img class="media" data-src="/" alt="" width="4" height="3"></a>'], '']);
108
108
  assert.deepStrictEqual(inspect(parser('![]{/ 4x3}')), [['<a href="/" target="_blank"><img class="media" data-src="/" alt="" width="4" height="3"></a>'], '']);
109
- assert.deepStrictEqual(inspect(parser('![]{/ aspect-ratio="4/3"}')), [['<a href="/" target="_blank"><img class="media" data-src="/" alt="" aspect-ratio="4/3"></a>'], '']);
110
- assert.deepStrictEqual(inspect(parser('![]{/ aspect-ratio="4/3" nofollow}')), [['<a href="/" rel="nofollow" target="_blank"><img class="media" data-src="/" alt="" aspect-ratio="4/3"></a>'], '']);
111
- assert.deepStrictEqual(inspect(parser('![]{/ 4:3}')), [['<a href="/" target="_blank"><img class="media" data-src="/" alt="" aspect-ratio="4/3"></a>'], '']);
109
+ assert.deepStrictEqual(inspect(parser('![]{/ aspect-ratio="4/3"}')), [['<a href="/" target="_blank"><img class="media" data-src="/" alt="" aspect-ratio="4/3" style="aspect-ratio: 4 / 3;"></a>'], '']);
110
+ assert.deepStrictEqual(inspect(parser('![]{/ aspect-ratio="4/3" nofollow}')), [['<a href="/" rel="nofollow" target="_blank"><img class="media" data-src="/" alt="" aspect-ratio="4/3" style="aspect-ratio: 4 / 3;"></a>'], '']);
111
+ assert.deepStrictEqual(inspect(parser('![]{/ 4:3}')), [['<a href="/" target="_blank"><img class="media" data-src="/" alt="" aspect-ratio="4/3" style="aspect-ratio: 4 / 3;"></a>'], '']);
112
112
  });
113
113
 
114
114
  });
@@ -48,6 +48,10 @@ export const media: MediaParser = lazy(() => creator(10, validate(['![', '!{'],
48
48
  assert(!el.matches('.invalid'));
49
49
  define(el, attributes('media', push([], el.classList), optspec, params));
50
50
  assert(el.matches('img') || !el.matches('.invalid'));
51
+ // Awaiting the generic support for attr().
52
+ if (el.hasAttribute('aspect-ratio')) {
53
+ el.style.aspectRatio = el.getAttribute('aspect-ratio')!;
54
+ }
51
55
  if (context.syntax?.inline?.link === false || cache && cache.tagName !== 'IMG') return [[el], rest];
52
56
  return fmap(
53
57
  link as MediaParser,
@@ -46,7 +46,6 @@ describe('Unit: parser/inline/reference', () => {
46
46
  assert.deepStrictEqual(inspect(parser('[[@a]]')), [['<sup class="reference"><span><a href="/@a" class="account">@a</a></span></sup>'], '']);
47
47
  assert.deepStrictEqual(inspect(parser('[[http://host]]')), [['<sup class="reference"><span><a href="http://host" target="_blank">http://host</a></span></sup>'], '']);
48
48
  assert.deepStrictEqual(inspect(parser('[[![]{a}]]')), [['<sup class="reference"><span>!<a href="a">a</a></span></sup>'], '']);
49
- assert.deepStrictEqual(inspect(parser('[[<a>]]')), [['<sup class="reference"><span>&lt;a&gt;</span></sup>'], '']);
50
49
  assert.deepStrictEqual(inspect(parser('[[[a]]]')), [['<sup class="reference"><span>[a]</span></sup>'], '']);
51
50
  assert.deepStrictEqual(inspect(parser('[[[[a]]]]')), [['<sup class="reference"><span>[[a]]</span></sup>'], '']);
52
51
  assert.deepStrictEqual(inspect(parser('[[((a))]]')), [['<sup class="reference"><span><span class="paren">((a))</span></span></sup>'], '']);
@@ -43,7 +43,6 @@ describe('Unit: parser/inline/strong', () => {
43
43
  assert.deepStrictEqual(inspect(parser('**a*b*c**')), [['<strong>a<em>b</em>c</strong>'], '']);
44
44
  assert.deepStrictEqual(inspect(parser('**a*b*c**d')), [['<strong>a<em>b</em>c</strong>'], 'd']);
45
45
  assert.deepStrictEqual(inspect(parser('**`a`**')), [['<strong><code data-src="`a`">a</code></strong>'], '']);
46
- assert.deepStrictEqual(inspect(parser('**<bdi>**')), [['<strong>&lt;bdi&gt;</strong>'], '']);
47
46
  assert.deepStrictEqual(inspect(parser('**(*a*)**')), [['<strong><span class="paren">(<em>a</em>)</span></strong>'], '']);
48
47
  assert.deepStrictEqual(inspect(parser('**(**a**)**')), [['<strong><span class="paren">(<strong>a</strong>)</span></strong>'], '']);
49
48
  });
@@ -155,8 +155,6 @@ describe('Unit: parser/inline', () => {
155
155
  assert.deepStrictEqual(inspect(parser('[(([a]{#}))]{#}')), [['<a href="#"><span class="paren">(<span class="paren">([a]{#})</span>)</span></a>'], '']);
156
156
  assert.deepStrictEqual(inspect(parser('"[[""]]')), [['"', '<sup class="reference"><span>""</span></sup>'], '']);
157
157
  assert.deepStrictEqual(inspect(parser('<http://host>')), [['<', '<a href="http://host" target="_blank">http://host</a>', '>'], '']);
158
- assert.deepStrictEqual(inspect(parser('<<bdi>a<</bdi>')), [['<', '<bdi>a&lt;</bdi>'], '']);
159
- assert.deepStrictEqual(inspect(parser('*<bdi>*`</bdi>`')), [['<em>&lt;bdi&gt;</em>', '<code data-src="`</bdi>`">&lt;/bdi&gt;</code>'], '']);
160
158
  assert.deepStrictEqual(inspect(parser('[~http://host')), [['[', '~', '<a href="http://host" target="_blank">http://host</a>'], '']);
161
159
  assert.deepStrictEqual(inspect(parser('[~a@b')), [['[', '~', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
162
160
  assert.deepStrictEqual(inspect(parser('[~~a~~]')), [['[', '<del>a</del>', ']'], '']);
@@ -4,7 +4,7 @@ import { union, focus, creator } from '../../combinator';
4
4
  import { str } from './str';
5
5
  import { html } from 'typed-dom/dom';
6
6
 
7
- export const delimiter = /[\s\x00-\x7F]|\S#|[、。!?][^\S\n]*(?=\\\n)/;
7
+ export const delimiter = /[\s\x00-\x7F]|\S#|[()、。!?][^\S\n]*(?=\\\n)/;
8
8
  export const nonWhitespace = /[\S\n]|$/;
9
9
  export const nonAlphanumeric = /[^0-9A-Za-z]|\S#|$/;
10
10
  const repeat = str(/^(.)\1*/);
@@ -1,4 +1,4 @@
1
- import { Object } from 'spica/global';
1
+ import { undefined, Object } from 'spica/global';
2
2
  import { html } from 'typed-dom/dom';
3
3
 
4
4
  const extensions = [
@@ -13,6 +13,9 @@ export function video(source: HTMLImageElement, url: URL): HTMLVideoElement | un
13
13
  'data-type': 'video',
14
14
  ...Object.fromEntries([...source.attributes]
15
15
  .map(attr => [attr.name, attr.value])),
16
+ style: source.hasAttribute('aspect-ratio')
17
+ ? `aspect-ratio: ${source.getAttribute('aspect-ratio')};`
18
+ : undefined,
16
19
  muted: '',
17
20
  controls: '',
18
21
  });