securemark 0.274.4 → 0.275.1

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.275.1
4
+
5
+ - Fix identifiers.
6
+
7
+ ## 0.275.0
8
+
9
+ - Fix identifiers.
10
+
3
11
  ## 0.274.4
4
12
 
5
13
  - Fix list item parser.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.274.4 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.275.1 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"));
@@ -6169,7 +6169,7 @@ const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)((0, comb
6169
6169
  Object.defineProperty(exports, "__esModule", ({
6170
6170
  value: true
6171
6171
  }));
6172
- exports.text = exports.index = exports.identity = exports.indexee = void 0;
6172
+ exports.text = exports.signature = exports.index = exports.identity = exports.indexee = void 0;
6173
6173
  const combinator_1 = __webpack_require__(2087);
6174
6174
  const memoize_1 = __webpack_require__(1808);
6175
6175
  const dom_1 = __webpack_require__(3252);
@@ -6181,17 +6181,18 @@ function indexee(parser, optional) {
6181
6181
  })]);
6182
6182
  }
6183
6183
  exports.indexee = indexee;
6184
- function identity(id, text, name = 'index') {
6184
+ function identity(id, text, type = 'index') {
6185
6185
  if (id === '') return undefined;
6186
6186
  text &&= text.trim().replace(/\s+/g, '_');
6187
6187
  if (text === '') return undefined;
6188
+ if (text.length <= 120 || type === '') return `${type}:${id ?? ''}:${text}`;
6188
6189
  const cs = [...text];
6189
- if (cs.length <= 100) return `${name}:${id ?? ''}:${text}`;
6190
- switch (name) {
6190
+ if (cs.length <= 120) return `${type}:${id ?? ''}:${text}`;
6191
+ switch (type) {
6191
6192
  case 'index':
6192
- return `${name}:${id ?? ''}:${cs.slice(0, 97).join('')}...`;
6193
+ return `${type}:${id ?? ''}:${cs.slice(0, 120 - 3).join('')}...`;
6193
6194
  case 'mark':
6194
- return `${name}:${id ?? ''}:${cs.slice(0, 50).join('')}...${cs.slice(-47).join('')}`;
6195
+ return `${type}:${id ?? ''}:${cs.slice(0, 38).join('')}...${cs.slice(cs.length / 2 - 38 / 2 | 0).slice(0, 38).join('')}...${cs.slice(-38).join('')}`;
6195
6196
  }
6196
6197
  }
6197
6198
  exports.identity = identity;
@@ -6201,9 +6202,43 @@ function index(source, optional = false) {
6201
6202
  const index = indexer?.getAttribute('data-index');
6202
6203
  if (index) return index;
6203
6204
  if (index === '' && optional) return '';
6204
- return (0, exports.text)(source);
6205
+ return signature(source);
6205
6206
  }
6206
6207
  exports.index = index;
6208
+ function signature(source) {
6209
+ const target = source.cloneNode(true);
6210
+ for (let es = target.querySelectorAll('code[data-src], .math[data-src], .label[data-label], .comment, rt, rp, br, .annotation, .reference, .checkbox, ul, ol'), len = es.length, i = 0; i < len; ++i) {
6211
+ const el = es[i];
6212
+ switch (el.tagName) {
6213
+ case 'CODE':
6214
+ el.replaceWith(el.getAttribute('data-src'));
6215
+ continue;
6216
+ case 'RT':
6217
+ case 'RP':
6218
+ case 'BR':
6219
+ case 'UL':
6220
+ case 'OL':
6221
+ el.remove();
6222
+ continue;
6223
+ }
6224
+ switch (el.className) {
6225
+ case 'math':
6226
+ el.replaceWith(el.getAttribute('data-src'));
6227
+ continue;
6228
+ case 'label':
6229
+ el.replaceWith(`[$${el.getAttribute('data-label').replace('$', '')}]`);
6230
+ continue;
6231
+ case 'comment':
6232
+ case 'checkbox':
6233
+ case 'annotation':
6234
+ case 'reference':
6235
+ el.remove();
6236
+ continue;
6237
+ }
6238
+ }
6239
+ return target.textContent.trim();
6240
+ }
6241
+ exports.signature = signature;
6207
6242
  exports.text = (0, memoize_1.reduce)(source => {
6208
6243
  const target = source.cloneNode(true);
6209
6244
  for (let es = target.querySelectorAll('code[data-src], .math[data-src], .comment, rt, rp, br, .annotation, .reference, .checkbox, ul, ol'), len = es.length, i = 0; i < len; ++i) {
@@ -6232,8 +6267,6 @@ exports.text = (0, memoize_1.reduce)(source => {
6232
6267
  continue;
6233
6268
  }
6234
6269
  }
6235
- // Better:
6236
- //return target.innerText;
6237
6270
  return target.textContent;
6238
6271
  });
6239
6272
 
@@ -6594,7 +6627,7 @@ exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, sourc
6594
6627
  }) => {
6595
6628
  const el = (0, dom_1.html)('mark', (0, dom_1.defrag)(bs));
6596
6629
  return [[(0, dom_1.define)(el, {
6597
- id: state & (256 /* State.annotation */ | 128 /* State.reference */) ? undefined : (0, indexee_1.identity)(id, (0, indexee_1.text)(el), 'mark')
6630
+ id: state & (256 /* State.annotation */ | 128 /* State.reference */) ? undefined : (0, indexee_1.identity)(id, (0, indexee_1.signature)(el), 'mark')
6598
6631
  }), el.id && (0, dom_1.html)('a', {
6599
6632
  href: `#${el.id}`
6600
6633
  })], rest];
@@ -7114,7 +7147,7 @@ function build(syntax, marker, splitter = '') {
7114
7147
  }
7115
7148
  }
7116
7149
  const abbr = ref.getAttribute('data-abbr') || undefined;
7117
- const identifier = (0, indexee_1.identity)(undefined, abbr ? abbr.match(/^(?:\S+ )+?(?:(?:January|February|March|April|May|June|August|September|October|November|December) \d{1,2}(?:-\d{0,2})?, \d{1,4}(?:-\d{0,4})?[a-z]?|n\.d\.)(?=,|$)/)?.[0] ?? abbr.match(/^[^,\s]+(?:,? [^,\s]+)*?(?: \d{1,4}(?:-\d{0,4})?[a-z]?(?=,|$)|(?=,(?: [a-z]+\.?)? [0-9]))/)?.[0] ?? abbr : (0, indexee_1.text)(ref.firstElementChild), 'mark')?.slice(6) || '';
7150
+ const identifier = abbr ? (0, indexee_1.identity)(undefined, abbr.match(/^(?:\S+ )+?(?:(?:January|February|March|April|May|June|August|September|October|November|December) \d{1,2}(?:-\d{0,2})?, \d{1,4}(?:-\d{0,4})?[a-z]?|n\.d\.)(?=,|$)/)?.[0] ?? abbr.match(/^[^,\s]+(?:,? [^,\s]+)*?(?: \d{1,4}(?:-\d{0,4})?[a-z]?(?=,|$)|(?=,(?: [a-z]+\.?)? [0-9]))/)?.[0] ?? abbr, '')?.slice(2) || '' : (0, indexee_1.identity)(undefined, (0, indexee_1.signature)(ref.firstElementChild), 'mark')?.slice(6) || '';
7118
7151
  const refSubindex = refSubindexes.get(identifier) + 1 || 1;
7119
7152
  refSubindexes.set(identifier, refSubindex);
7120
7153
  const refId = opts.id !== '' ? `${syntax}:${opts.id ?? ''}:ref:${identifier}:${refSubindex}` : undefined;
@@ -7131,7 +7164,7 @@ function build(syntax, marker, splitter = '') {
7131
7164
  initial && defs.set(identifier, def);
7132
7165
  const defIndex = initial ? total + defs.size : defIndexes.get(def);
7133
7166
  initial && defIndexes.set(def, defIndex);
7134
- const title = initial ? (0, indexee_1.text)(ref.firstElementChild) : titles.get(identifier);
7167
+ const title = initial ? (0, indexee_1.text)(ref.firstElementChild).trim() : titles.get(identifier);
7135
7168
  initial && titles.set(identifier, title);
7136
7169
  ref.firstElementChild.hasAttribute('hidden') ? ref.lastElementChild.remove() : ref.firstElementChild.setAttribute('hidden', '');
7137
7170
  (0, dom_1.define)(ref, {
@@ -7158,7 +7191,7 @@ function build(syntax, marker, splitter = '') {
7158
7191
  }, marker(defIndex, abbr)));
7159
7192
  def.lastElementChild.appendChild((0, dom_1.html)('a', {
7160
7193
  href: refId && `#${refId}`,
7161
- title: abbr && (0, indexee_1.text)((0, dom_1.frag)(ref.firstElementChild.cloneNode(true).childNodes)).trim() || undefined
7194
+ title: abbr && (initial ? title : (0, indexee_1.text)(ref.firstElementChild).trim()) || undefined
7162
7195
  }, `^${++refIndex}`));
7163
7196
  }
7164
7197
  if (note || defs.size > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.274.4",
3
+ "version": "0.275.1",
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",
@@ -207,8 +207,8 @@ describe('Unit: parser/api/parse', () => {
207
207
  [...parse('$-a\n$$\n$$\n\n(($-a[[^B]]))[[^B|$-a]]', { notes }).children].map(el => el.outerHTML),
208
208
  [
209
209
  '<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>',
210
- '<p><sup class="annotation" id="annotation::ref:(1):1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="B"><span></span></sup></span><a href="#annotation::def:(1):1">*1</a></sup><sup class="reference" data-abbr="B" id="reference::ref:B:1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a></span><a href="#reference::def:B">[B]</a></sup></p>',
211
- '<ol class="annotations"><li id="annotation::def:(1):1" data-marker="*1"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="B" id="reference::ref:B:2" title="(1)"><span hidden=""></span><a href="#reference::def:B">[B]</a></sup></span><sup><a href="#annotation::ref:(1):1">^1</a></sup></li></ol>',
210
+ '<p><sup class="annotation" id="annotation::ref:[$-a]:1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="B"><span></span></sup></span><a href="#annotation::def:[$-a]:1">*1</a></sup><sup class="reference" data-abbr="B" id="reference::ref:B:1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a></span><a href="#reference::def:B">[B]</a></sup></p>',
211
+ '<ol class="annotations"><li id="annotation::def:[$-a]:1" data-marker="*1"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="B" id="reference::ref:B:2" title="(1)"><span hidden=""></span><a href="#reference::def:B">[B]</a></sup></span><sup><a href="#annotation::ref:[$-a]:1">^1</a></sup></li></ol>',
212
212
  ]);
213
213
  assert.deepStrictEqual(
214
214
  notes.references.outerHTML,
@@ -9,28 +9,29 @@ export function indexee(parser: Parser<HTMLElement, MarkdownParser.Context>, opt
9
9
  return fmap(parser, ([el], _, { id }) => [define(el, { id: identity(id, index(el, optional)) })]);
10
10
  }
11
11
 
12
- export function identity(id: string | undefined, text: string, name: 'index' | 'mark' = 'index'): string | undefined {
12
+ export function identity(id: string | undefined, text: string, type: 'index' | 'mark' | '' = 'index'): string | undefined {
13
13
  assert(!id?.match(/[^0-9a-z/-]/i));
14
14
  assert(!text.includes('\n'));
15
15
  if (id === '') return undefined;
16
16
  text &&= text.trim().replace(/\s+/g, '_');
17
17
  if (text === '') return undefined;
18
+ if (text.length <= 120 || type === '') return `${type}:${id ?? ''}:${text}`;
18
19
  const cs = [...text];
19
- if (cs.length <= 100) return `${name}:${id ?? ''}:${text}`;
20
- switch (name) {
20
+ if (cs.length <= 120) return `${type}:${id ?? ''}:${text}`;
21
+ switch (type) {
21
22
  case 'index':
22
- return `${name}:${id ?? ''}:${cs.slice(0, 97).join('')}...`;
23
+ return `${type}:${id ?? ''}:${cs.slice(0, 120 - 3).join('')}...`;
23
24
  case 'mark':
24
- return `${name}:${id ?? ''}:${cs.slice(0, 50).join('')}...${cs.slice(-47).join('')}`;
25
+ return `${type}:${id ?? ''}:${cs.slice(0, 38).join('')}...${cs.slice(cs.length / 2 - 38 / 2 | 0).slice(0, 38).join('')}...${cs.slice(-38).join('')}`;
25
26
  }
26
27
  assert(false);
27
28
  }
28
- assert(identity(undefined, '0'.repeat(100 - 1) + 1)!.slice(7) === '0'.repeat(100 - 1) + 1);
29
- assert(identity(undefined, '0'.repeat(100) + 1)!.slice(7) === '0'.repeat(97) + '...');
30
- assert(identity(undefined, '0'.repeat(200) + 1)!.slice(7) === '0'.repeat(97) + '...');
31
- assert(identity(undefined, '0'.repeat(100 - 1) + 1, 'mark')!.slice(6) === '0'.repeat(100 - 1) + 1);
32
- assert(identity(undefined, '0'.repeat(100) + 1, 'mark')!.slice(6) === '0'.repeat(50) + '...' + '0'.repeat(47 - 1) + 1);
33
- assert(identity(undefined, '0'.repeat(200) + 1, 'mark')!.slice(6) === '0'.repeat(50) + '...' + '0'.repeat(47 - 1) + 1);
29
+ assert(identity(undefined, '0'.repeat(120 - 1) + 1)!.slice(7) === '0'.repeat(120 - 1) + 1);
30
+ assert(identity(undefined, '0'.repeat(120) + 1)!.slice(7) === '0'.repeat(117) + '...');
31
+ assert(identity(undefined, '0'.repeat(200) + 1)!.slice(7) === '0'.repeat(117) + '...');
32
+ assert(identity(undefined, '0'.repeat(120 - 1) + 1, 'mark')!.slice(6) === '0'.repeat(120 - 1) + 1);
33
+ assert(identity(undefined, '0'.repeat(41) + '1'.repeat(38) + '2'.repeat(41) + 3, 'mark')!.slice(6) === '0'.repeat(38) + '...' + '1'.repeat(38) + '...' + '2'.repeat(38 - 1) + 3);
34
+ assert(identity(undefined, '0'.repeat(81) + '1'.repeat(38) + '2'.repeat(81) + 3, 'mark')!.slice(6) === '0'.repeat(38) + '...' + '1'.repeat(38) + '...' + '2'.repeat(38 - 1) + 3);
34
35
 
35
36
  export function index(source: Element, optional = false): string {
36
37
  assert(source instanceof DocumentFragment || !source.matches('.indexer'));
@@ -40,7 +41,43 @@ export function index(source: Element, optional = false): string {
40
41
  const index = indexer?.getAttribute('data-index');
41
42
  if (index) return index;
42
43
  if (index === '' && optional) return '';
43
- return text(source);
44
+ return signature(source);
45
+ }
46
+
47
+ export function signature(source: Element | DocumentFragment): string {
48
+ assert(!navigator.userAgent.includes('Chrome') || !source.querySelector('br:not(:has(+ :is(ul, ol)))'));
49
+ const target = source.cloneNode(true) as typeof source;
50
+ for (let es = target.querySelectorAll('code[data-src], .math[data-src], .label[data-label], .comment, rt, rp, br, .annotation, .reference, .checkbox, ul, ol'),
51
+ len = es.length, i = 0; i < len; ++i) {
52
+ const el = es[i];
53
+ switch (el.tagName) {
54
+ case 'CODE':
55
+ el.replaceWith(el.getAttribute('data-src')!);
56
+ continue;
57
+ case 'RT':
58
+ case 'RP':
59
+ case 'BR':
60
+ case 'UL':
61
+ case 'OL':
62
+ el.remove();
63
+ continue;
64
+ }
65
+ switch (el.className) {
66
+ case 'math':
67
+ el.replaceWith(el.getAttribute('data-src')!);
68
+ continue;
69
+ case 'label':
70
+ el.replaceWith(`[$${el.getAttribute('data-label')!.replace('$', '')}]`);
71
+ continue;
72
+ case 'comment':
73
+ case 'checkbox':
74
+ case 'annotation':
75
+ case 'reference':
76
+ el.remove();
77
+ continue;
78
+ }
79
+ }
80
+ return target.textContent!.trim();
44
81
  }
45
82
 
46
83
  export const text = reduce((source: Element | DocumentFragment): string => {
@@ -73,7 +110,5 @@ export const text = reduce((source: Element | DocumentFragment): string => {
73
110
  continue;
74
111
  }
75
112
  }
76
- // Better:
77
- //return target.innerText;
78
113
  return target.textContent!;
79
114
  });
@@ -1,7 +1,7 @@
1
1
  import { MarkParser } from '../inline';
2
2
  import { union, some, syntax, constraint, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
- import { identity, text } from './extension/indexee';
4
+ import { identity, signature } from './extension/indexee';
5
5
  import { str } from '../source';
6
6
  import { startTight, blankWith } from '../visibility';
7
7
  import { Syntax, State } from '../context';
@@ -23,7 +23,7 @@ export const mark: MarkParser = lazy(() => surround(
23
23
  define(el, {
24
24
  id: state! & (State.annotation | State.reference)
25
25
  ? undefined
26
- : identity(id, text(el), 'mark'),
26
+ : identity(id, signature(el), 'mark'),
27
27
  }),
28
28
  el.id && html('a', { href: `#${el.id}` }),
29
29
  ], rest];
@@ -1,9 +1,10 @@
1
1
  import { figure } from './figure';
2
+ import { ParserOptions } from '../../..';
2
3
  import { parse as parse_ } from '../../parser';
3
4
  import { html } from 'typed-dom/dom';
4
5
  import { normalize } from '../../debug.test';
5
6
 
6
- const parse = (s: string) => parse_(s, { test: true });
7
+ const parse = (s: string, o?: ParserOptions) => parse_(s, { test: true, ...o });
7
8
 
8
9
  describe('Unit: parser/processor/figure', () => {
9
10
  describe('figure', () => {
@@ -278,15 +279,17 @@ describe('Unit: parser/processor/figure', () => {
278
279
  it('id', () => {
279
280
  const target = parse([
280
281
  '$test-a\n> ',
281
- '$test-a',
282
- ].join('\n\n'));
282
+ '==$test-a==',
283
+ '- $test-a',
284
+ ].join('\n\n'), { id: '0' });
283
285
  for (let i = 0; i < 3; ++i) {
284
286
  [...figure(target, undefined, { id: '0' })];
285
287
  assert.deepStrictEqual(
286
288
  [...target.children].map(el => el.outerHTML),
287
289
  [
288
290
  '<figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:0:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
289
- '<p><a class="label" data-label="test-a" href="#label:0:test-a">Test 1</a></p>',
291
+ '<p><mark id="mark:0:[$test-a]"><a class="label" data-label="test-a" href="#label:0:test-a">Test 1</a></mark><a href="#mark:0:[$test-a]"></a></p>',
292
+ '<ul><li id="index:0:[$test-a]"><a class="label" data-label="test-a" href="#label:0:test-a">Test 1</a></li></ul>',
290
293
  ]);
291
294
  }
292
295
  });
@@ -1,6 +1,6 @@
1
- import { identity, text } from '../inline/extension/indexee';
1
+ import { identity, signature, text } from '../inline/extension/indexee';
2
2
  import { markInvalid, unmarkInvalid } from '../util';
3
- import { frag, html, define } from 'typed-dom/dom';
3
+ import { html, define } from 'typed-dom/dom';
4
4
 
5
5
  export function* note(
6
6
  target: ParentNode & Node,
@@ -70,15 +70,16 @@ function build(
70
70
  }
71
71
  }
72
72
  const abbr = ref.getAttribute('data-abbr') || undefined;
73
- const identifier = identity(
74
- undefined,
75
- abbr
76
- ? abbr.match(/^(?:\S+ )+?(?:(?:January|February|March|April|May|June|August|September|October|November|December) \d{1,2}(?:-\d{0,2})?, \d{1,4}(?:-\d{0,4})?[a-z]?|n\.d\.)(?=,|$)/)?.[0] ??
77
- abbr.match(/^[^,\s]+(?:,? [^,\s]+)*?(?: \d{1,4}(?:-\d{0,4})?[a-z]?(?=,|$)|(?=,(?: [a-z]+\.?)? [0-9]))/)?.[0] ??
78
- abbr
79
- : text(ref.firstElementChild!),
80
- 'mark')
81
- ?.slice(6) || '';
73
+ const identifier = abbr
74
+ ? identity(
75
+ undefined,
76
+ (
77
+ abbr.match(/^(?:\S+ )+?(?:(?:January|February|March|April|May|June|August|September|October|November|December) \d{1,2}(?:-\d{0,2})?, \d{1,4}(?:-\d{0,4})?[a-z]?|n\.d\.)(?=,|$)/)?.[0] ??
78
+ abbr.match(/^[^,\s]+(?:,? [^,\s]+)*?(?: \d{1,4}(?:-\d{0,4})?[a-z]?(?=,|$)|(?=,(?: [a-z]+\.?)? [0-9]))/)?.[0] ??
79
+ abbr
80
+ ),
81
+ '')?.slice(2) || ''
82
+ : identity(undefined, signature(ref.firstElementChild!), 'mark')?.slice(6) || '';
82
83
  const refSubindex = refSubindexes.get(identifier)! + 1 || 1;
83
84
  refSubindexes.set(identifier, refSubindex);
84
85
  const refId = opts.id !== ''
@@ -107,7 +108,7 @@ function build(
107
108
  : defIndexes.get(def)!;
108
109
  initial && defIndexes.set(def, defIndex);
109
110
  const title = initial
110
- ? text(ref.firstElementChild!)
111
+ ? text(ref.firstElementChild!).trim()
111
112
  : titles.get(identifier)!;
112
113
  initial && titles.set(identifier, title);
113
114
  assert(syntax !== 'annotation' || title);
@@ -139,7 +140,7 @@ function build(
139
140
  html('a',
140
141
  {
141
142
  href: refId && `#${refId}`,
142
- title: abbr && text(frag(ref.firstElementChild!.cloneNode(true).childNodes)).trim() || undefined,
143
+ title: abbr && (initial ? title : text(ref.firstElementChild!).trim()) || undefined,
143
144
  },
144
145
  `^${++refIndex}`));
145
146
  }