securemark 0.300.2 → 0.300.4

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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.300.4
4
+
5
+ - Refactoring.
6
+
7
+ ## 0.300.3
8
+
9
+ - Refactoring.
10
+
3
11
  ## 0.300.2
4
12
 
5
13
  - Refactoring.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.300.2 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.300.4 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("Prism"), require("DOMPurify"));
@@ -2528,8 +2528,7 @@ function bind(target, settings) {
2528
2528
  };
2529
2529
  for (const el of (0, figure_1.figure)(next(0)?.parentNode ?? target, settings.notes, options)) {
2530
2530
  el ? yield {
2531
- type: 'figure',
2532
- value: el
2531
+ type: 'figure'
2533
2532
  } : yield {
2534
2533
  type: 'break',
2535
2534
  value: 'figure'
@@ -6355,7 +6354,7 @@ class Input extends parser_1.Input {
6355
6354
  this.resources ??= {
6356
6355
  clock: -1,
6357
6356
  interval: 200,
6358
- recursions: [10 || 0 /* Recursion.document */, 100 || 0 /* Recursion.block */, 100 || 0 /* Recursion.inline */, 100 || 0 /* Recursion.bracket */]
6357
+ recursions: [20 || 0 /* Recursion.document */, 100 || 0 /* Recursion.block */, 100 || 0 /* Recursion.inline */, 100 || 0 /* Recursion.bracket */]
6359
6358
  };
6360
6359
  this.segment = segment ?? 0 /* Segment.unknown */;
6361
6360
  this.header = header ?? true;
@@ -6413,29 +6412,37 @@ exports.document = (() => {
6413
6412
  const loop = (0, parser_2.build)(segment_1.parser, block_1.block);
6414
6413
  return (0, combinator_1.always)([(input, output) => {
6415
6414
  input.id = input.id === '' ? '' : input.local ? (0, util_1.randomID)() : input.id;
6416
- input.memory = input.notes ?? {
6417
- interpolation: true,
6418
- references: (0, dom_1.html)('ol', {
6415
+ input.memory = {
6416
+ interpolation: !input.notes,
6417
+ references: input.notes?.references ?? (0, dom_1.html)('ol', {
6419
6418
  class: 'references'
6420
6419
  })
6421
6420
  };
6422
6421
  output.push();
6423
6422
  return output.context;
6424
6423
  }, (0, combinator_1.recursion)(0 /* Recursion.document */, (0, combinator_1.force)(() => loop)), (input, output) => {
6425
- const doc = (0, dom_1.frag)((0, util_1.unwrap)(output.pop()));
6424
+ const {
6425
+ memory
6426
+ } = input;
6427
+ const doc = memory.doc = (0, dom_1.frag)((0, util_1.unwrap)(output.pop()));
6426
6428
  output.append(new parser_1.Node(doc));
6427
- if (input.test && !input.local) return output.context;
6429
+ if (input.test && !input.local) return parser_1.Result.skip;
6430
+ memory.orphan = !memory.references.parentNode;
6431
+ memory.orphan && doc.appendChild(memory.references);
6432
+ return output.context;
6433
+ }, input => conv((0, figure_1.figure)(input.memory.doc, input.memory, input)), input => conv((0, note_1.note)(input.memory.doc, input.memory, input)), (input, output) => {
6428
6434
  const {
6429
6435
  memory
6430
6436
  } = input;
6431
- const orphan = !memory.references.parentNode;
6432
- orphan && doc.appendChild(memory.references);
6433
- for (const _ of (0, figure_1.figure)(doc, memory, input));
6434
- for (const _ of (0, note_1.note)(doc, memory, input));
6435
- orphan && !memory.interpolation && memory.references.remove();
6437
+ memory.orphan && !memory.interpolation && memory.references.remove();
6436
6438
  return output.context;
6437
6439
  }]);
6438
6440
  })();
6441
+ function conv(iterable) {
6442
+ const iter = iterable[Symbol.iterator]();
6443
+ const cont = [(_, output) => iter.next().done ? output.context : cont];
6444
+ return cont;
6445
+ }
6439
6446
 
6440
6447
  /***/ },
6441
6448
 
@@ -8569,6 +8576,7 @@ function repeat(opener, after, closer, recursion, parser, cons, termination = (n
8569
8576
  const {
8570
8577
  source,
8571
8578
  position,
8579
+ linebreak,
8572
8580
  resources: {
8573
8581
  recursions
8574
8582
  }
@@ -8581,16 +8589,18 @@ function repeat(opener, after, closer, recursion, parser, cons, termination = (n
8581
8589
  input.position = position;
8582
8590
  return parser_1.Result.skip;
8583
8591
  }
8584
- let depth = i / opener.length + 1 | 0;
8592
+ const depth = i / opener.length + 1 | 0;
8585
8593
  (0, combinator_1.recur)(output, recursions, recursion, depth, true);
8586
8594
  input.memory = {
8587
8595
  position,
8596
+ linebreak,
8588
8597
  i,
8589
8598
  lead: 0,
8590
8599
  follow: 0,
8591
8600
  state: false,
8592
8601
  depth
8593
8602
  };
8603
+ input.linebreak = 0;
8594
8604
  output.push();
8595
8605
  return loop;
8596
8606
  }, (input, output) => {
@@ -8603,6 +8613,7 @@ function repeat(opener, after, closer, recursion, parser, cons, termination = (n
8603
8613
  } = input;
8604
8614
  (0, combinator_1.recur)(output, recursions, recursion, -m.depth);
8605
8615
  m.depth = 0;
8616
+ input.linebreak ||= m.linebreak;
8606
8617
  const prefix = m.i;
8607
8618
  m.i = 0;
8608
8619
  for (let len = (0, alias_1.min)(prefix, source.length - input.position); m.i < len && source[input.position + m.i] === closer[0];) {
@@ -8633,6 +8644,7 @@ function repeat(opener, after, closer, recursion, parser, cons, termination = (n
8633
8644
  const advance = input.position - pos;
8634
8645
  m.i -= advance;
8635
8646
  m.follow -= advance;
8647
+ (0, combinator_1.recur)(output, recursions, recursion, -(advance / closer.length | 0));
8636
8648
  m.depth -= advance / closer.length | 0;
8637
8649
  }
8638
8650
  continue;
@@ -8643,7 +8655,10 @@ function repeat(opener, after, closer, recursion, parser, cons, termination = (n
8643
8655
  }, parser, (input, output) => {
8644
8656
  const {
8645
8657
  source,
8646
- memory: m
8658
+ memory: m,
8659
+ resources: {
8660
+ recursions
8661
+ }
8647
8662
  } = input;
8648
8663
  const {
8649
8664
  lead
@@ -8671,6 +8686,7 @@ function repeat(opener, after, closer, recursion, parser, cons, termination = (n
8671
8686
  const advance = input.position - pos;
8672
8687
  m.i -= advance;
8673
8688
  m.follow -= advance;
8689
+ (0, combinator_1.recur)(output, recursions, recursion, -(advance / closer.length | 0));
8674
8690
  m.depth -= advance / closer.length | 0;
8675
8691
  }
8676
8692
  m.i -= opener.length, m.follow -= closer.length;
@@ -9637,7 +9653,7 @@ function* figure(target, notes, opts = {}) {
9637
9653
  let base = '0';
9638
9654
  let bases = base.split('.');
9639
9655
  for (let defs = target instanceof Element ? target.querySelectorAll(`:scope > ${selector}`) : target.querySelectorAll(`:not(* > *)${selector}`), len = defs.length, i = 0; i < len; ++i) {
9640
- yield;
9656
+ if (~i << 32 - 8 === 0) yield;
9641
9657
  const def = defs[i];
9642
9658
  const {
9643
9659
  tagName
@@ -9710,7 +9726,7 @@ function* figure(target, notes, opts = {}) {
9710
9726
  (0, util_1.unmarkInvalid)(ref);
9711
9727
  }
9712
9728
  if (ref.hash.slice(1) === def.id && ref.innerText === figindex) continue;
9713
- yield (0, dom_1.define)(ref, {
9729
+ (0, dom_1.define)(ref, {
9714
9730
  class: opts.local ? `${ref.className} local` : undefined,
9715
9731
  href: opts.id !== '' ? `#${def.id}` : undefined
9716
9732
  }, figindex);
@@ -9720,7 +9736,6 @@ function* figure(target, notes, opts = {}) {
9720
9736
  if (opts.id !== '' && !ref.classList.contains('invalid')) {
9721
9737
  (0, util_1.markInvalid)(ref, 'label', 'reference', messages.reference);
9722
9738
  }
9723
- yield ref;
9724
9739
  }
9725
9740
  }
9726
9741
  exports.figure = figure;
@@ -9812,14 +9827,17 @@ function build(syntax, list, selector, marker, splitter = '') {
9812
9827
  let format;
9813
9828
  let refIndex = 0;
9814
9829
  for (let len = refs.length, i = 0; i < len; ++i) {
9830
+ if (~i << 32 - 8 === 0) yield;
9815
9831
  const ref = refs[i];
9816
9832
  if (splitter) for (let splitter; splitter = splitters[iSplitters]; ++iSplitters) {
9817
9833
  const pos = splitter?.compareDocumentPosition(ref) ?? 0;
9818
9834
  if (pos & (Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_DISCONNECTED)) break;
9819
9835
  if (~iSplitters << 32 - 8 === 0) yield;
9820
9836
  if (splitter.classList.contains(list) && splitter.nextElementSibling !== splitters[iSplitters + 1]) {
9821
- yield* proc(splitter);
9822
- splitter.remove();
9837
+ const note = splitter;
9838
+ proc(note);
9839
+ note.remove();
9840
+ yield note;
9823
9841
  continue;
9824
9842
  }
9825
9843
  if (defs.size > 0) {
@@ -9827,7 +9845,8 @@ function build(syntax, list, selector, marker, splitter = '') {
9827
9845
  const note = splitter.classList.contains(list) ? splitter : target.insertBefore((0, dom_1.html)('ol', {
9828
9846
  class: list
9829
9847
  }), splitter);
9830
- yield* proc(note, defs);
9848
+ proc(note, defs);
9849
+ yield note;
9831
9850
  }
9832
9851
  }
9833
9852
  const {
@@ -9889,31 +9908,33 @@ function build(syntax, list, selector, marker, splitter = '') {
9889
9908
  href: refId && `#${refId}`,
9890
9909
  title: abbr && text || undefined
9891
9910
  }, `^${++refIndex}`));
9892
- yield;
9893
9911
  }
9894
9912
  if (note || defs.size > 0) {
9895
9913
  const splitter = splitters[iSplitters++];
9896
9914
  note ??= splitter?.classList.contains(list) ? splitter : target.insertBefore((0, dom_1.html)('ol', {
9897
9915
  class: list
9898
9916
  }), splitter ?? bottom);
9899
- yield* proc(note, defs);
9917
+ proc(note, defs);
9918
+ yield note;
9900
9919
  }
9901
9920
  if (splitter) for (let splitter; splitter = splitters[iSplitters]; ++iSplitters) {
9902
9921
  if (~iSplitters << 32 - 8 === 0) yield;
9903
9922
  if (splitter.classList.contains(list)) {
9904
- yield* proc(splitter);
9923
+ const note = splitter;
9924
+ proc(note);
9905
9925
  splitter.remove();
9926
+ yield note;
9906
9927
  }
9907
9928
  }
9908
9929
  };
9909
9930
  }
9910
- function* proc(note, defs) {
9931
+ function proc(note, defs) {
9911
9932
  for (let defs = note.children, i = defs.length; i--;) {
9912
- yield note.removeChild(defs[i]);
9933
+ note.removeChild(defs[i]);
9913
9934
  }
9914
9935
  if (!defs) return;
9915
9936
  for (const [, def] of defs) {
9916
- yield note.appendChild(def);
9937
+ note.appendChild(def);
9917
9938
  }
9918
9939
  defs.clear();
9919
9940
  }
package/index.d.ts CHANGED
@@ -42,8 +42,8 @@ export interface ParserSettings {
42
42
  export type Progress =
43
43
  | { readonly type: 'segment'; readonly value: string; }
44
44
  | { readonly type: 'block'; readonly value: HTMLElement; }
45
- | { readonly type: 'figure'; readonly value: HTMLAnchorElement; }
46
- | { readonly type: 'note'; readonly value: HTMLLIElement | HTMLElement; }
45
+ | { readonly type: 'figure'; }
46
+ | { readonly type: 'note'; readonly value: HTMLOListElement; }
47
47
  | { readonly type: 'break'; readonly value: 'segment' | 'block' | 'parser' | 'figure' | 'note'; }
48
48
  | { readonly type: 'cancel'; };
49
49
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.300.2",
3
+ "version": "0.300.4",
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",
@@ -10,8 +10,10 @@ describe('Unit: api/bind', () => {
10
10
  const result = iter.next();
11
11
  if (result.done) break;
12
12
  switch (result.value.type) {
13
- case 'break':
14
13
  case 'segment':
14
+ case 'figure':
15
+ case 'note':
16
+ case 'break':
15
17
  --i;
16
18
  continue;
17
19
  case 'block':
package/src/api/bind.ts CHANGED
@@ -129,7 +129,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
129
129
  for (const el of figure(next(0)?.parentNode ?? target, settings.notes, options)) {
130
130
  assert(rev === revision);
131
131
  el
132
- ? yield { type: 'figure', value: el }
132
+ ? yield { type: 'figure' }
133
133
  : yield { type: 'break', value: 'figure' };
134
134
  if (rev !== revision) return yield { type: 'cancel' };
135
135
  }
@@ -28,7 +28,7 @@ export class Input<M extends object = object> extends Ipt<M> {
28
28
  clock: -1,
29
29
  interval: 200,
30
30
  recursions: [
31
- 10 || Recursion.document,
31
+ 20 || Recursion.document,
32
32
  100 || Recursion.block,
33
33
  100 || Recursion.inline,
34
34
  100 || Recursion.bracket,
@@ -1,6 +1,6 @@
1
1
  import { MarkdownParser } from '../../markdown';
2
2
  import { Input, Recursion } from './context';
3
- import { Parser, Node } from '../combinator/parser';
3
+ import { Parser, Result, Node } from '../combinator/parser';
4
4
  import { always, force, recursion } from '../combinator';
5
5
  import { build } from './parser';
6
6
  import { parser as segment } from './segment';
@@ -12,8 +12,10 @@ import { frag, html } from 'typed-dom/dom';
12
12
 
13
13
  export const document: MarkdownParser = (() => {
14
14
  interface Memory {
15
- readonly interpolation?: boolean;
15
+ readonly interpolation: boolean;
16
16
  readonly references: HTMLOListElement;
17
+ doc?: DocumentFragment;
18
+ orphan?: boolean;
17
19
  }
18
20
  const loop = build(segment, block);
19
21
  return always<Parser<DocumentFragment | HTMLElement, Input<Memory>>>([
@@ -22,9 +24,9 @@ export const document: MarkdownParser = (() => {
22
24
  input.id === '' ? '' :
23
25
  input.local ? randomID() :
24
26
  input.id;
25
- input.memory = input.notes ?? {
26
- interpolation: true,
27
- references: html('ol', { class: 'references' }),
27
+ input.memory = {
28
+ interpolation: !input.notes,
29
+ references: input.notes?.references ?? html('ol', { class: 'references' }),
28
30
  };
29
31
  output.push();
30
32
  return output.context;
@@ -32,17 +34,34 @@ export const document: MarkdownParser = (() => {
32
34
  recursion(Recursion.document, force(() => loop)),
33
35
  (input, output) => {
34
36
  assert(input.position === input.source.length);
35
- const doc = frag(unwrap(output.pop()));
37
+ const { memory } = input;
38
+ const doc = memory.doc = frag(unwrap(output.pop()));
36
39
  output.append(new Node(doc));
37
40
  assert(input.id !== '' || !doc.querySelector('[id], .index[href], .label[href], .annotation > a[href], .reference > a[href]'));
38
- if (input.test && !input.local) return output.context;
41
+ if (input.test && !input.local) return Result.skip;
42
+ memory.orphan = !memory.references.parentNode;
43
+ memory.orphan && doc.appendChild(memory.references);
44
+ return output.context;
45
+ },
46
+ input =>
47
+ conv(figure(input.memory.doc!, input.memory, input)),
48
+ input =>
49
+ conv(note(input.memory.doc!, input.memory, input)),
50
+ (input, output) => {
39
51
  const { memory } = input;
40
- const orphan = !memory.references.parentNode;
41
- orphan && doc.appendChild(memory.references);
42
- for (const _ of figure(doc, memory, input));
43
- for (const _ of note(doc, memory, input));
44
- orphan && !memory.interpolation && memory.references.remove();
52
+ memory.orphan && !memory.interpolation && memory.references.remove();
45
53
  return output.context;
46
54
  },
47
55
  ]);
48
56
  })();
57
+
58
+ function conv<T>(iterable: Iterable<T>): Result<never> {
59
+ const iter = iterable[Symbol.iterator]();
60
+ const cont: Result<T> = [
61
+ (_, output) =>
62
+ iter.next().done
63
+ ? output.context
64
+ : cont,
65
+ ];
66
+ return cont;
67
+ }
@@ -142,6 +142,7 @@ describe('Unit: parser/inline', () => {
142
142
  assert.deepStrictEqual(inspect(parser, input('(([:a\n]')), [['<span class="bracket">(<span class="bracket">(<span class="invalid">[:a\n]</span></span></span>'], '']);
143
143
  assert.deepStrictEqual(inspect(parser, input('(({{\n}}')), [['<span class="bracket">(<span class="bracket">(<span class="template">{{<br>}}</span></span></span>'], '']);
144
144
  assert.deepStrictEqual(inspect(parser, input('"((""))')), [['"', '<span class="paren">(<span class="paren">(</span></span>', '"', '"', ')', ')'], '']);
145
+ assert.deepStrictEqual(inspect(parser, input('0\n((a))')), [['0', '<br>', '<sup class="annotation"><span>a</span></sup>'], '']);
145
146
  assert.deepStrictEqual(inspect(parser, input('[[[a]]')), [['[', '<sup class="reference"><span>a</span></sup>'], '']);
146
147
  assert.deepStrictEqual(inspect(parser, input('[[[[a]]')), [['[', '[', '<sup class="reference"><span>a</span></sup>'], '']);
147
148
  assert.deepStrictEqual(inspect(parser, input('[[[[a]]]]')), [['<sup class="reference"><span>[[a]]</span></sup>'], '']);
@@ -34,6 +34,7 @@ export function repeat<T extends HTMLElement | string>(
34
34
  const test = tester(after, false);
35
35
  interface Memory {
36
36
  readonly position: number;
37
+ linebreak: number;
37
38
  i: number;
38
39
  lead: number;
39
40
  follow: number;
@@ -42,7 +43,7 @@ export function repeat<T extends HTMLElement | string>(
42
43
  }
43
44
  const cont: Result<T, Input<Memory>> = [
44
45
  (input, output) => {
45
- const { source, position, resources: { recursions } } = input;
46
+ const { source, position, linebreak, resources: { recursions } } = input;
46
47
  if (!source.startsWith(opener, input.position)) return Result.skip;
47
48
  let i = opener.length;
48
49
  for (; source[input.position + i] === source[input.position];) ++i;
@@ -51,16 +52,18 @@ export function repeat<T extends HTMLElement | string>(
51
52
  input.position = position;
52
53
  return Result.skip;
53
54
  }
54
- let depth = i / opener.length + 1 | 0;
55
+ const depth = i / opener.length + 1 | 0;
55
56
  recur(output, recursions, recursion, depth, true);
56
57
  input.memory = {
57
58
  position,
59
+ linebreak,
58
60
  i,
59
61
  lead: 0,
60
62
  follow: 0,
61
63
  state: false,
62
64
  depth,
63
65
  };
66
+ input.linebreak = 0;
64
67
  output.push();
65
68
  return loop;
66
69
  },
@@ -68,6 +71,7 @@ export function repeat<T extends HTMLElement | string>(
68
71
  const { source, memory: m, resources: { recursions } } = input;
69
72
  recur(output, recursions, recursion, -m.depth);
70
73
  m.depth = 0;
74
+ input.linebreak ||= m.linebreak;
71
75
  const prefix = m.i;
72
76
  m.i = 0;
73
77
  for (let len = min(prefix, source.length - input.position); m.i < len && source[input.position + m.i] === closer[0];) {
@@ -94,6 +98,7 @@ export function repeat<T extends HTMLElement | string>(
94
98
  const advance = input.position - pos;
95
99
  m.i -= advance;
96
100
  m.follow -= advance;
101
+ recur(output, recursions, recursion, -(advance / closer.length | 0));
97
102
  m.depth -= advance / closer.length | 0;
98
103
  }
99
104
  continue;
@@ -104,7 +109,7 @@ export function repeat<T extends HTMLElement | string>(
104
109
  },
105
110
  parser,
106
111
  (input, output) => {
107
- const { source, memory: m } = input;
112
+ const { source, memory: m, resources: { recursions } } = input;
108
113
  const { lead } = m;
109
114
  input.range = input.position - m.position - m.i + opener.length;
110
115
  if (!output.state) return;
@@ -131,6 +136,7 @@ export function repeat<T extends HTMLElement | string>(
131
136
  const advance = input.position - pos;
132
137
  m.i -= advance;
133
138
  m.follow -= advance;
139
+ recur(output, recursions, recursion, -(advance / closer.length | 0));
134
140
  m.depth -= advance / closer.length | 0;
135
141
  }
136
142
  m.i -= opener.length, m.follow -= closer.length;
@@ -11,7 +11,7 @@ export function* figure(
11
11
  readonly id?: string;
12
12
  readonly local?: boolean;
13
13
  } = {},
14
- ): Generator<HTMLAnchorElement | undefined, undefined, undefined> {
14
+ ): Generator<undefined, undefined, undefined> {
15
15
  const selector = ':is(figure[data-label], h1, h2)';
16
16
  const refs = new MultiQueue<string, HTMLAnchorElement>(
17
17
  !notes || notes.references.parentNode === target
@@ -34,7 +34,7 @@ export function* figure(
34
34
  ? target.querySelectorAll(`:scope > ${selector}`)
35
35
  : target.querySelectorAll(`:not(* > *)${selector}`),
36
36
  len = defs.length, i = 0; i < len; ++i) {
37
- yield;
37
+ if (~i << 32 - 8 === 0) yield;
38
38
  const def = defs[i];
39
39
  assert(def.parentNode === target || !def.parentNode);
40
40
  const { tagName } = def;
@@ -127,7 +127,7 @@ export function* figure(
127
127
  unmarkInvalid(ref);
128
128
  }
129
129
  if (ref.hash.slice(1) === def.id && ref.innerText === figindex) continue;
130
- yield define(ref,
130
+ define(ref,
131
131
  {
132
132
  class: opts.local ? `${ref.className} local` : undefined,
133
133
  href: opts.id !== '' ? `#${def.id}` : undefined,
@@ -139,7 +139,6 @@ export function* figure(
139
139
  if (opts.id !== '' && !ref.classList.contains('invalid')) {
140
140
  markInvalid(ref, 'label', 'reference', messages.reference);
141
141
  }
142
- yield ref;
143
142
  }
144
143
  assert(opts.id !== '' || !target.querySelector('[id], .index[href], .label[href], .annotation > a[href], .reference > a[href]'));
145
144
  assert(opts.id !== '' || !notes?.references.querySelector('[id], .index[href], .label[href]'));
@@ -18,7 +18,7 @@ describe('Unit: processor/note', () => {
18
18
  it('1', () => {
19
19
  const target = run(parse('((a b))'));
20
20
  for (let i = 0; i < 3; ++i) {
21
- assert.deepStrictEqual([...note(target)].length, i === 0 ? 2 : 3);
21
+ assert.deepStrictEqual([...note(target)].length, 1);
22
22
  assert.deepStrictEqual(
23
23
  [...target.children].map(el => normalize(el.outerHTML)),
24
24
  [
@@ -40,7 +40,7 @@ describe('Unit: processor/note', () => {
40
40
  it('2', () => {
41
41
  const target = run(parse('((1))((12345678901234567890))'));
42
42
  for (let i = 0; i < 3; ++i) {
43
- assert.deepStrictEqual([...note(target)].length, i === 0 ? 4 : 6);
43
+ assert.deepStrictEqual([...note(target)].length, 1);
44
44
  assert.deepStrictEqual(
45
45
  [...target.children].map(el => normalize(el.outerHTML)),
46
46
  [
@@ -203,7 +203,7 @@ describe('Unit: processor/note', () => {
203
203
  it('id', () => {
204
204
  const target = run(parse('((a b))'));
205
205
  for (let i = 0; i < 3; ++i) {
206
- assert.deepStrictEqual([...note(target, undefined, { id: '0' })].length, i === 0 ? 2 : 3);
206
+ assert.deepStrictEqual([...note(target, undefined, { id: '0' })].length, 1);
207
207
  assert.deepStrictEqual(
208
208
  [...target.children].map(el => normalize(el.outerHTML)),
209
209
  [
@@ -14,7 +14,7 @@ export function* note(
14
14
  readonly local?: boolean;
15
15
  } = {},
16
16
  bottom: Node | null = null,
17
- ): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
17
+ ): Generator<HTMLOListElement | undefined, undefined, undefined> {
18
18
  const referenceRefMemory = referenceRefsMemoryCaller(target);
19
19
  const annotationRefMemory = annotationRefsMemoryCaller(target);
20
20
  for (const memory of [referenceRefMemory, annotationRefMemory]) {
@@ -77,7 +77,7 @@ function build(
77
77
  readonly local?: boolean;
78
78
  } = {},
79
79
  bottom: Node | null = null,
80
- ): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
80
+ ): Generator<HTMLOListElement | undefined, undefined, undefined> {
81
81
  const refInfoCaller = memoize((ref: HTMLElement) => {
82
82
  const content = ref.firstElementChild!;
83
83
  const abbr = ref.getAttribute('data-abbr') ?? '';
@@ -119,6 +119,7 @@ function build(
119
119
  let format: 'number' | 'abbr';
120
120
  let refIndex = 0;
121
121
  for (let len = refs.length, i = 0; i < len; ++i) {
122
+ if (~i << 32 - 8 === 0) yield;
122
123
  const ref = refs[i];
123
124
  if (splitter) for (let splitter; splitter = splitters[iSplitters]; ++iSplitters) {
124
125
  assert(splitter.parentNode === target || !splitter.parentNode);
@@ -126,8 +127,10 @@ function build(
126
127
  if (pos & (Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_DISCONNECTED)) break;
127
128
  if (~iSplitters << 32 - 8 === 0) yield;
128
129
  if (splitter.classList.contains(list) && splitter.nextElementSibling !== splitters[iSplitters + 1]) {
129
- yield* proc(splitter as HTMLOListElement);
130
- splitter.remove();
130
+ const note = splitter as HTMLOListElement;
131
+ proc(note);
132
+ note.remove();
133
+ yield note;
131
134
  continue;
132
135
  }
133
136
  if (defs.size > 0) {
@@ -137,8 +140,9 @@ function build(
137
140
  ? splitter as HTMLOListElement
138
141
  : target.insertBefore(html('ol', { class: list }), splitter);
139
142
  assert(note.parentNode);
140
- yield* proc(note, defs);
143
+ proc(note, defs);
141
144
  assert(defs.size === 0);
145
+ yield note;
142
146
  }
143
147
  }
144
148
  const { content, identifier, abbr, text } = refInfoCaller(ref);
@@ -209,21 +213,23 @@ function build(
209
213
  title: abbr && text || undefined,
210
214
  },
211
215
  `^${++refIndex}`));
212
- yield;
213
216
  }
214
217
  if (note || defs.size > 0) {
215
218
  const splitter = splitters[iSplitters++];
216
219
  note ??= splitter?.classList.contains(list)
217
220
  ? splitter as HTMLOListElement
218
221
  : target.insertBefore(html('ol', { class: list }), splitter ?? bottom);
219
- yield* proc(note, defs);
222
+ proc(note, defs);
220
223
  assert(defs.size === 0);
224
+ yield note;
221
225
  }
222
226
  if (splitter) for (let splitter; splitter = splitters[iSplitters]; ++iSplitters) {
223
227
  if (~iSplitters << 32 - 8 === 0) yield;
224
228
  if (splitter.classList.contains(list)) {
225
- yield* proc(splitter as HTMLOListElement);
229
+ const note = splitter as HTMLOListElement;
230
+ proc(note);
226
231
  splitter.remove();
232
+ yield note;
227
233
  }
228
234
  }
229
235
  assert(opts.id !== '' || !target.querySelector('[id], .index[href], .label[href], .annotation > a[href], .reference > a[href]'));
@@ -231,13 +237,13 @@ function build(
231
237
  };
232
238
  }
233
239
 
234
- function* proc(note: HTMLOListElement, defs?: Map<string, HTMLLIElement>): Generator<HTMLLIElement | undefined, undefined, undefined> {
240
+ function proc(note: HTMLOListElement, defs?: Map<string, HTMLLIElement>): void {
235
241
  for (let defs = note.children, i = defs.length; i--;) {
236
- yield note.removeChild(defs[i] as HTMLLIElement);
242
+ note.removeChild(defs[i] as HTMLLIElement);
237
243
  }
238
244
  if (!defs) return;
239
245
  for (const [, def] of defs) {
240
- yield note.appendChild(def);
246
+ note.appendChild(def);
241
247
  }
242
248
  defs.clear();
243
249
  }