securemark 0.262.1 → 0.263.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 +9 -1
- package/dist/index.js +520 -703
- package/karma.conf.js +1 -1
- package/package.json +8 -8
- package/src/combinator/control/manipulation/convert.ts +4 -4
- package/src/parser/block/extension/fig.test.ts +2 -1
- package/src/parser/block/extension/fig.ts +14 -2
- package/src/parser/inline/extension/indexee.ts +2 -2
- package/src/parser/locale.ts +2 -2
- package/src/parser/processor/figure.ts +4 -4
- package/src/parser/processor/footnote.ts +9 -8
- package/src/util/info.ts +2 -2
- package/src/util/quote.ts +4 -3
- package/src/util/toc.ts +3 -3
package/karma.conf.js
CHANGED
|
@@ -6,7 +6,7 @@ module.exports = function (config) {
|
|
|
6
6
|
{ pattern: 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js', watched: false, served: false, included: true, integrity: 'sha512-2iwCHjuj+PmdCyvb88rMOch0UcKQxVHi/gsAml1fN3eg82IDaO/cdzzeXX4iF2VzIIes7pODE1/G0ts3QBwslA==' },
|
|
7
7
|
{ pattern: 'https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js', watched: false, served: false, included: true, integrity: 'sha512-XnVGk21Ij51MbU8XezQpkwZ1/GA8b5qmoVGIOdJLBYycutjkaeemipzRJP7P6mEJl99OfnweA7M3e4WLfuG7Aw==' },
|
|
8
8
|
{ pattern: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js', watched: false, served: false, included: true, integrity: 'sha512-n/4gHW3atM3QqRcbCn6ewmpxcLAHGaDjpEBu4xZd47N0W2oQ+6q7oc3PXstrJYXcbNU1OHdQ1T7pAP+gi5Yu8g==' },
|
|
9
|
-
{ pattern: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/prism.min.js', watched: false, served: false, included: true, integrity: '
|
|
9
|
+
{ pattern: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/prism.min.js', watched: false, served: false, included: true, integrity: 'sha512-RDQSW3KoqJMiX0L/UBgwBmH1EmRYp8LBOiLaA8rBHIy+7OGP/7Gxg8vbt8wG4ZYd29P0Fnoq6+LOytCqx3cyoQ==' },
|
|
10
10
|
{ pattern: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/plugins/autoloader/prism-autoloader.min.js', watched: false, served: false, included: true, integrity: 'sha512-fTl/qcO1VgvKtOMApX2PdZzkziyr2stM65GYPLGuYMnuMm1z2JLJG6XVU7C/mR+E7xBUqCivykuhlzfqxXBXbg==' },
|
|
11
11
|
{ pattern: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.0/es5/tex-chtml.min.js', watched: false, served: false, included: true, integrity: 'sha512-93xLZnNMlYI6xaQPf/cSdXoBZ23DThX7VehiGJJXB76HTTalQKPC5CIHuFX8dlQ5yzt6baBQRJ4sDXhzpojRJA==' },
|
|
12
12
|
{ pattern: 'https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.8/purify.js', watched: false, served: false, included: true, integrity: 'sha512-QaF+0tDlqVmwZaQSc0kImgYmw+Cd66TxA5D9X70I5V9BNSqk6yBTbyqw2VEUsVYV5OTbxw8HD9d45on1wvYv7g==' },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "securemark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.263.0",
|
|
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,26 +34,26 @@
|
|
|
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.
|
|
37
|
+
"@typescript-eslint/parser": "^5.38.1",
|
|
38
38
|
"babel-loader": "^8.2.5",
|
|
39
39
|
"babel-plugin-unassert": "^3.2.0",
|
|
40
40
|
"concurrently": "^7.4.0",
|
|
41
|
-
"eslint": "^8.
|
|
41
|
+
"eslint": "^8.24.0",
|
|
42
42
|
"eslint-plugin-redos": "^4.4.1",
|
|
43
43
|
"eslint-webpack-plugin": "^3.2.0",
|
|
44
44
|
"glob": "^8.0.3",
|
|
45
|
-
"karma": "^6.4.
|
|
45
|
+
"karma": "^6.4.1",
|
|
46
46
|
"karma-chrome-launcher": "^3.1.1",
|
|
47
47
|
"karma-coverage": "^2.2.0",
|
|
48
48
|
"karma-firefox-launcher": "^2.1.2",
|
|
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.
|
|
52
|
+
"npm-check-updates": "^16.3.2",
|
|
53
53
|
"semver": "^7.3.7",
|
|
54
|
-
"spica": "0.0.
|
|
55
|
-
"ts-loader": "^9.
|
|
56
|
-
"typed-dom": "^0.0.
|
|
54
|
+
"spica": "0.0.640",
|
|
55
|
+
"ts-loader": "^9.4.1",
|
|
56
|
+
"typed-dom": "^0.0.310",
|
|
57
57
|
"typescript": "4.8.3",
|
|
58
58
|
"webpack": "^5.74.0",
|
|
59
59
|
"webpack-cli": "^4.10.0",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Parser, check } from '../../data/parser';
|
|
1
|
+
import { Parser, Ctx, Context, check } from '../../data/parser';
|
|
2
2
|
|
|
3
|
-
export function convert<P extends Parser<unknown>>(conv: (source: string) => string, parser: P): P;
|
|
4
|
-
export function convert<T>(conv: (source: string) => string, parser: Parser<T>): Parser<T> {
|
|
3
|
+
export function convert<P extends Parser<unknown>>(conv: (source: string, context: Context<P>) => string, parser: P): P;
|
|
4
|
+
export function convert<T>(conv: (source: string, context: Ctx) => string, parser: Parser<T>): Parser<T> {
|
|
5
5
|
assert(parser);
|
|
6
6
|
return ({ source, context }) => {
|
|
7
7
|
if (source === '') return;
|
|
8
|
-
const src = conv(source);
|
|
8
|
+
const src = conv(source, context);
|
|
9
9
|
if (src === '') return [[], ''];
|
|
10
10
|
context.offset ??= 0;
|
|
11
11
|
context.offset += source.length - src.length;
|
|
@@ -10,7 +10,6 @@ describe('Unit: parser/block/extension/fig', () => {
|
|
|
10
10
|
assert.deepStrictEqual(inspect(parser('\n!https://host\n')), undefined);
|
|
11
11
|
assert.deepStrictEqual(inspect(parser('[$group-name]\nhttps://host')), undefined);
|
|
12
12
|
assert.deepStrictEqual(inspect(parser('[$group-name]\nhttps://host\n')), undefined);
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('[$group-name]\n!https://host\na')), undefined);
|
|
14
13
|
assert.deepStrictEqual(inspect(parser('[$group-name]\n !https://host')), undefined);
|
|
15
14
|
assert.deepStrictEqual(inspect(parser('[$group-name]\n\n!https://host')), undefined);
|
|
16
15
|
assert.deepStrictEqual(inspect(parser('[$group-name]a\nhttps://host')), undefined);
|
|
@@ -43,6 +42,8 @@ describe('Unit: parser/block/extension/fig', () => {
|
|
|
43
42
|
assert.deepStrictEqual(inspect(parser('[$group-name]\n!> _a_')), [['<figure data-type="quote" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><blockquote><section><p><em>a</em></p><h2>References</h2><ol class="references"></ol></section></blockquote></div></figure>'], '']);
|
|
44
43
|
assert.deepStrictEqual(inspect(parser('[$group-name]\n![]{https://host}')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
45
44
|
assert.deepStrictEqual(inspect(parser('[$group-name]\n![]{https://host}\n')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
45
|
+
assert.deepStrictEqual(inspect(parser('[$group-name]\n!https://host\ncaption')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext">caption</span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('[$group-name]\n!https://host\ncaption\n')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext">caption</span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
46
47
|
assert.deepStrictEqual(inspect(parser('$group-name\n!https://host')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
47
48
|
});
|
|
48
49
|
|
|
@@ -8,6 +8,7 @@ import { segment as seg_math } from '../mathblock';
|
|
|
8
8
|
import { segment as seg_table } from './table';
|
|
9
9
|
import { segment as seg_blockquote } from '../blockquote';
|
|
10
10
|
import { segment as seg_placeholder } from './placeholder';
|
|
11
|
+
import { media, shortmedia } from '../../inline';
|
|
11
12
|
|
|
12
13
|
import FigParser = ExtensionParser.FigParser;
|
|
13
14
|
|
|
@@ -25,10 +26,21 @@ export const segment: FigParser.SegmentParser = block(validate(['[$', '$'],
|
|
|
25
26
|
])));
|
|
26
27
|
|
|
27
28
|
export const fig: FigParser = block(rewrite(segment, verify(convert(
|
|
28
|
-
source => {
|
|
29
|
+
(source, context) => {
|
|
29
30
|
const fence = (/^[^\n]*\n!?>+\s/.test(source) && source.match(/^~{3,}(?=[^\S\n]*$)/mg) || [])
|
|
30
31
|
.reduce((max, fence) => fence > max ? fence : max, '~~') + '~';
|
|
31
|
-
return
|
|
32
|
+
return parser({ source, context })
|
|
33
|
+
? `${fence}figure ${source.replace(/^(.+\n.+\n)([\S\s]+?)\n?$/, '$1\n$2')}\n${fence}`
|
|
34
|
+
: `${fence}figure ${source}\n\n${fence}`;
|
|
32
35
|
},
|
|
33
36
|
union([figure])),
|
|
34
37
|
([el]) => el.tagName === 'FIGURE')));
|
|
38
|
+
|
|
39
|
+
const parser = sequence([
|
|
40
|
+
line(close(seg_label, /^(?=\s).*\n/)),
|
|
41
|
+
line(union([
|
|
42
|
+
media,
|
|
43
|
+
shortmedia,
|
|
44
|
+
])),
|
|
45
|
+
some(contentline),
|
|
46
|
+
]);
|
|
@@ -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(
|
|
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':
|
package/src/parser/locale.ts
CHANGED
|
@@ -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(
|
|
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 {
|
|
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
|
|
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(
|
|
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(
|
|
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 {
|
|
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(
|
|
15
|
-
for (let es = querySelectorAll(
|
|
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
|
|
42
|
+
const buffer = new MultiQueue<string, HTMLElement>();
|
|
43
43
|
const titles = new Map<string, string>();
|
|
44
44
|
// Bug: Firefox
|
|
45
|
-
//const splitters = push([], querySelectorAll(
|
|
45
|
+
//const splitters = push([], target.querySelectorAll(`:scope > :is(${splitter ?? '_'})`));
|
|
46
46
|
const splitters: Element[] = [];
|
|
47
|
-
for (let es = querySelectorAll(
|
|
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(
|
|
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>(
|
|
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(
|
|
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(
|
|
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 =
|
|
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(
|
|
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) {
|