securemark 0.262.0 → 0.262.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.262.0",
3
+ "version": "0.262.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",
@@ -34,11 +34,11 @@
34
34
  "@types/mocha": "9.1.1",
35
35
  "@types/power-assert": "1.5.8",
36
36
  "@types/prismjs": "1.26.0",
37
- "@typescript-eslint/parser": "^5.36.2",
37
+ "@typescript-eslint/parser": "^5.37.0",
38
38
  "babel-loader": "^8.2.5",
39
39
  "babel-plugin-unassert": "^3.2.0",
40
40
  "concurrently": "^7.4.0",
41
- "eslint": "^8.23.0",
41
+ "eslint": "^8.23.1",
42
42
  "eslint-plugin-redos": "^4.4.1",
43
43
  "eslint-webpack-plugin": "^3.2.0",
44
44
  "glob": "^8.0.3",
@@ -49,11 +49,11 @@
49
49
  "karma-mocha": "^2.0.1",
50
50
  "karma-power-assert": "^1.0.0",
51
51
  "mocha": "^10.0.0",
52
- "npm-check-updates": "^16.1.1",
52
+ "npm-check-updates": "^16.1.3",
53
53
  "semver": "^7.3.7",
54
- "spica": "0.0.622",
54
+ "spica": "0.0.626",
55
55
  "ts-loader": "^9.3.1",
56
- "typed-dom": "^0.0.305",
56
+ "typed-dom": "^0.0.309",
57
57
  "typescript": "4.8.3",
58
58
  "webpack": "^5.74.0",
59
59
  "webpack-cli": "^4.10.0",
@@ -1,4 +1,4 @@
1
- import { undefined, Function } from 'spica/global';
1
+ import { global, undefined } from 'spica/global';
2
2
  import { isArray } from 'spica/alias';
3
3
  import { Parser, Ctx, Tree, Context, eval, exec, check } from '../../data/parser';
4
4
 
@@ -15,15 +15,13 @@ export function validate<T>(patterns: string | RegExp | (string | RegExp)[], has
15
15
  assert(patterns.length > 0);
16
16
  assert(patterns.every(pattern => pattern instanceof RegExp ? !pattern.flags.match(/[gmy]/) && pattern.source.startsWith('^') : true));
17
17
  assert(parser);
18
- const match: (source: string) => boolean = Function([
19
- '"use strict";',
20
- 'return source =>',
21
- '0',
22
- ...patterns.map(pattern =>
18
+ const match: (source: string) => boolean = global.eval([
19
+ 'source =>',
20
+ patterns.map(pattern =>
23
21
  typeof pattern === 'string'
24
22
  ? `|| source.slice(0, ${pattern.length}) === '${pattern}'`
25
- : `|| /${pattern.source}/${pattern.flags}.test(source)`),
26
- ].join(''))();
23
+ : `|| /${pattern.source}/${pattern.flags}.test(source)`).join('').slice(2),
24
+ ].join(''));
27
25
  return ({ source, context }) => {
28
26
  if (source === '') return;
29
27
  if (!match(source)) return;
@@ -1,4 +1,4 @@
1
- import { undefined, Function } from 'spica/global';
1
+ import { undefined } from 'spica/global';
2
2
  import { Parser, Ctx, Tree, Context, SubParsers, SubTree } from '../parser';
3
3
 
4
4
  export function union<P extends Parser<unknown>>(parsers: SubParsers<P>): SubTree<P> extends Tree<P> ? P : Parser<SubTree<P>, Context<P>, SubParsers<P>>;
@@ -9,12 +9,17 @@ export function union<T, D extends Parser<T>[]>(parsers: D): Parser<T, Ctx, D> {
9
9
  return () => undefined;
10
10
  case 1:
11
11
  return parsers[0];
12
+ case 2:
13
+ return input => parsers[0](input) ?? parsers[1](input);
14
+ case 3:
15
+ return input => parsers[0](input) ?? parsers[1](input) ?? parsers[2](input);
12
16
  default:
13
- return Function('parsers', [
14
- '"use strict";',
15
- 'return (input, context) =>',
16
- '0',
17
- ...parsers.map((_, i) => `|| parsers[${i}](input, context)`),
18
- ].join('\n'))(parsers);
17
+ return input => {
18
+ for (let i = 0; i < parsers.length; ++i) {
19
+ const parser = parsers[i];
20
+ const result = parser(input);
21
+ if (result) return result;
22
+ }
23
+ };
19
24
  }
20
25
  }
@@ -3,7 +3,6 @@ import { MarkdownParser } from '../../../../markdown';
3
3
  import { Parser } from '../../../combinator/data/parser';
4
4
  import { fmap } from '../../../combinator';
5
5
  import { define } from 'typed-dom/dom';
6
- import { querySelectorAll } from 'typed-dom/query';
7
6
 
8
7
  export function indexee<P extends Parser<unknown, MarkdownParser.Context>>(parser: P, optional?: boolean): P;
9
8
  export function indexee(parser: Parser<HTMLElement, MarkdownParser.Context>, optional?: boolean): Parser<HTMLElement> {
@@ -28,7 +27,8 @@ export function text(source: HTMLElement | DocumentFragment, optional = false):
28
27
  if (index) return index;
29
28
  assert(!source.querySelector('.annotation, br'));
30
29
  const target = source.cloneNode(true) as typeof source;
31
- for (let es = querySelectorAll(target, 'code[data-src], .math[data-src], .comment, rt, rp, .reference, .checkbox, ul, ol'), i = 0; i < es.length; ++i) {
30
+ for (let es = target.querySelectorAll('code[data-src], .math[data-src], .comment, rt, rp, .reference, .checkbox, ul, ol'),
31
+ len = es.length, i = 0; i < len; ++i) {
32
32
  const el = es[i];
33
33
  switch (el.tagName) {
34
34
  case 'CODE':
@@ -2,7 +2,6 @@ import { Parser } from '../combinator/data/parser';
2
2
  import { fmap } from '../combinator';
3
3
  import { japanese } from './locale/ja';
4
4
  import { html } from 'typed-dom/dom';
5
- import { querySelectorAll } from 'typed-dom/query';
6
5
 
7
6
  export function localize<P extends Parser<HTMLElement | string>>(parser: P): P;
8
7
  export function localize(parser: Parser<HTMLElement | string>): Parser<HTMLElement | string> {
@@ -11,7 +10,8 @@ export function localize(parser: Parser<HTMLElement | string>): Parser<HTMLEleme
11
10
  const el = ns.length === 1 && typeof ns[0] === 'object'
12
11
  ? ns[0]
13
12
  : html('div', ns);
14
- for (let es = querySelectorAll(el, '.linebreak:not(:empty)'), i = 0; i < es.length; ++i) {
13
+ for (let es = el.querySelectorAll('.linebreak:not(:empty)'),
14
+ len = es.length, i = 0; i < len; ++i) {
15
15
  const el = es[i];
16
16
  assert(el.firstChild!.textContent === ' ');
17
17
  if (!check(el)) continue;
@@ -1,6 +1,6 @@
1
1
  import { Infinity, Set, Map } from 'spica/global';
2
2
  import { number as calculate, isFixed } from '../inline/extension/label';
3
- import { MultiMap } from 'spica/multimap';
3
+ import { MultiQueue } from 'spica/queue';
4
4
  import { push } from 'spica/array';
5
5
  import { define } from 'typed-dom/dom';
6
6
  import { querySelectorAll } from 'typed-dom/query';
@@ -10,7 +10,7 @@ export function* figure(
10
10
  footnotes?: { readonly references: HTMLOListElement; },
11
11
  opts: { readonly id?: string; } = {},
12
12
  ): Generator<HTMLAnchorElement | undefined, undefined, undefined> {
13
- const refs = new MultiMap<string, HTMLAnchorElement>(push(
13
+ const refs = new MultiQueue<string, HTMLAnchorElement>(push(
14
14
  querySelectorAll(target, 'a.label:not(.disabled)[data-label]'),
15
15
  footnotes && querySelectorAll(footnotes.references, 'a.label:not(.disabled)') || [])
16
16
  .map(el => [el.getAttribute('data-label')!, el]));
@@ -20,9 +20,9 @@ export function* figure(
20
20
  let bases: readonly string[] = base.split('.');
21
21
  let index: readonly string[] = bases;
22
22
  // Bug: Firefox
23
- //for (let defs = querySelectorAll(target, ':scope > figure[data-label], :scope > h1, :scope > h2'), len = defs.length, i = 0; i < len; ++i) {
23
+ //for (let defs = target.querySelectorAll(':scope > figure[data-label], :scope > h1, :scope > h2'), len = defs.length, i = 0; i < len; ++i) {
24
24
  for (
25
- let defs = querySelectorAll(target, 'figure[data-label], h1, h2'),
25
+ let defs = target.querySelectorAll('figure[data-label], h1, h2'),
26
26
  len = defs.length, i = 0; i < len; ++i) {
27
27
  yield;
28
28
  const def = defs[i];
@@ -1,8 +1,7 @@
1
1
  import { undefined, Infinity, Map, Node } from 'spica/global';
2
2
  import { text } from '../inline/extension/indexee';
3
- import { MultiMap } from 'spica/multimap';
3
+ import { MultiQueue } from 'spica/queue';
4
4
  import { frag, html, define } from 'typed-dom/dom';
5
- import { querySelectorAll } from 'typed-dom/query';
6
5
 
7
6
  export function* footnote(
8
7
  target: ParentNode & Node,
@@ -11,8 +10,9 @@ export function* footnote(
11
10
  bottom: Node | null = null,
12
11
  ): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
13
12
  // Bug: Firefox
14
- //querySelectorAll(target, `:scope > .annotations`).forEach(el => el.remove());
15
- for (let es = querySelectorAll(target, `.annotations`), i = 0; i < es.length; ++i) {
13
+ //target.querySelectorAll(`:scope > .annotations`).forEach(el => el.remove());
14
+ for (let es = target.querySelectorAll(`.annotations`),
15
+ len = es.length, i = 0; i < len; ++i) {
16
16
  const el = es[i];
17
17
  el.parentNode === target && el.remove();
18
18
  }
@@ -39,12 +39,13 @@ function build(
39
39
  bottom: Node | null = null,
40
40
  ): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
41
41
  const defs = new Map<string, HTMLLIElement>();
42
- const buffer = new MultiMap<string, HTMLElement>();
42
+ const buffer = new MultiQueue<string, HTMLElement>();
43
43
  const titles = new Map<string, string>();
44
44
  // Bug: Firefox
45
- //const splitters = push([], querySelectorAll(target, `:scope > :is(${splitter ?? '_'})`));
45
+ //const splitters = push([], target.querySelectorAll(`:scope > :is(${splitter ?? '_'})`));
46
46
  const splitters: Element[] = [];
47
- for (let es = querySelectorAll(target, splitter ?? '_'), i = 0; i < es.length; ++i) {
47
+ for (let es = target.querySelectorAll(splitter ?? '_'),
48
+ len = es.length, i = 0; i < len; ++i) {
48
49
  const el = es[i];
49
50
  el.parentNode === target && splitters.push(el);
50
51
  }
@@ -52,7 +53,7 @@ function build(
52
53
  let total = 0;
53
54
  let style: 'count' | 'abbr';
54
55
  for (
55
- let refs = querySelectorAll(target, `sup.${syntax}:not(.disabled)`),
56
+ let refs = target.querySelectorAll(`sup.${syntax}:not(.disabled)`),
56
57
  len = refs.length, i = 0; i < len; ++i) {
57
58
  yield;
58
59
  const ref = refs[i];
package/src/util/info.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Info } from '../..';
2
2
  import { scope } from './scope';
3
- import { querySelectorAll } from 'typed-dom/query';
4
3
 
5
4
  export function info(source: DocumentFragment | HTMLElement | ShadowRoot): Info {
6
5
  const match = scope(source, '.invalid');
@@ -19,7 +18,8 @@ export function info(source: DocumentFragment | HTMLElement | ShadowRoot): Info
19
18
 
20
19
  function find<T extends HTMLElement>(selector: string): T[] {
21
20
  const acc: T[] = [];
22
- for (let es = querySelectorAll<T>(source, selector), i = 0; i < es.length; ++i) {
21
+ for (let es = source.querySelectorAll<T>(selector),
22
+ len = es.length, i = 0; i < len; ++i) {
23
23
  const el = es[i];
24
24
  match(el) && acc.push(el);
25
25
  }
package/src/util/quote.ts CHANGED
@@ -2,14 +2,14 @@ import { Element } from 'spica/global';
2
2
  import { exec } from '../combinator/data/parser';
3
3
  import { cite } from '../parser/block/reply/cite';
4
4
  import { define } from 'typed-dom/dom';
5
- import { querySelectorAll } from 'typed-dom/query';
6
5
 
7
6
  export function quote(anchor: string, range: Range): string {
8
7
  if (exec(cite({ source: `>>${anchor}`, context: {} })) !== '') throw new Error(`Invalid anchor: ${anchor}`);
9
8
  fit(range);
10
9
  const node = trim(range.cloneContents());
11
10
  if (!node.firstChild) return '';
12
- for (let es = querySelectorAll(node, 'code[data-src], .math[data-src], .media[data-src], rt, rp'), i = 0; i < es.length; ++i) {
11
+ for (let es = node.querySelectorAll('code[data-src], .math[data-src], .media[data-src], rt, rp'),
12
+ len = es.length, i = 0; i < len; ++i) {
13
13
  const el = es[i];
14
14
  switch (true) {
15
15
  case el.matches('code'):
@@ -36,7 +36,8 @@ export function quote(anchor: string, range: Range): string {
36
36
  node.prepend(`>>${anchor}\n> `);
37
37
  anchor = '';
38
38
  }
39
- for (let es = querySelectorAll(node, 'br'), i = 0; i < es.length; ++i) {
39
+ for (let es = node.querySelectorAll('br'),
40
+ len = es.length, i = 0; i < len; ++i) {
40
41
  const el = es[i];
41
42
  if (anchor && el.nextSibling instanceof Element && el.nextSibling.matches('.cite, .quote')) {
42
43
  el.replaceWith(`\n>${el.nextSibling.matches('.quote.invalid') ? ' ' : ''}`);
package/src/util/toc.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import { undefined } from 'spica/global';
2
2
  import { push } from 'spica/array';
3
3
  import { html } from 'typed-dom/dom';
4
- import { querySelectorAll } from 'typed-dom/query';
5
4
 
6
5
  // Bug: Firefox
7
- //const selector = 'h1 h2 h3 h4 h5 h6 aside.aside'.split(' ').map(s => `:scope > ${s}[id]`).join();
6
+ //const selector = `:scope > :is(h1, h2, h3, h4, h5, h6, aside.aside)[id]`;
8
7
  const selector = ':is(h1, h2, h3, h4, h5, h6, aside.aside)[id]';
9
8
 
10
9
  export function toc(source: DocumentFragment | HTMLElement | ShadowRoot): HTMLUListElement {
11
10
  const hs: HTMLHeadingElement[] = [];
12
- for (let es = querySelectorAll(source, selector), i = 0; i < es.length; ++i) {
11
+ for (let es = source.querySelectorAll(selector),
12
+ len = es.length, i = 0; i < len; ++i) {
13
13
  const el = es[i];
14
14
  assert(el.parentNode === source);
15
15
  switch (el.tagName) {