securemark 0.280.0 → 0.280.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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.280.2
4
+
5
+ - Refactoring.
6
+
7
+ ## 0.280.1
8
+
9
+ - Refactoring.
10
+
3
11
  ## 0.280.0
4
12
 
5
13
  - Decrease resource size to 20,000.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.280.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.280.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("Prism"), require("DOMPurify"));
@@ -3325,9 +3325,6 @@ const alias_1 = __webpack_require__(5406);
3325
3325
  const parser_1 = __webpack_require__(6728);
3326
3326
  const memo_1 = __webpack_require__(1090);
3327
3327
  function reset(base, parser) {
3328
- if (!('memo' in base)) {
3329
- base.memo = undefined;
3330
- }
3331
3328
  const changes = Object.entries(base);
3332
3329
  const values = Array(changes.length);
3333
3330
  return ({
@@ -3346,44 +3343,33 @@ function context(base, parser) {
3346
3343
  }
3347
3344
  exports.context = context;
3348
3345
  function apply(parser, source, context, changes, values, reset = false) {
3349
- if (context) for (let i = 0; i < changes.length; ++i) {
3346
+ for (let i = 0; i < changes.length; ++i) {
3350
3347
  const change = changes[i];
3351
3348
  const prop = change[0];
3352
3349
  switch (prop) {
3353
3350
  case 'resources':
3354
- if (!reset) break;
3355
- if (prop in context && !(0, alias_1.hasOwnProperty)(context, prop)) break;
3356
- context[prop] = (0, alias_1.ObjectCreate)(change[1]);
3357
- break;
3358
- // @ts-expect-error
3359
- case 'memo':
3360
- if (!reset) break;
3361
- context.memo = new memo_1.Memo({
3362
- targets: context.memo?.targets
3363
- });
3364
- // fallthrough
3365
- default:
3366
- values[i] = context[prop];
3367
- context[prop] = change[1];
3351
+ context[prop] ??= (0, alias_1.ObjectCreate)(change[1]);
3352
+ continue;
3368
3353
  }
3354
+ values[i] = context[prop];
3355
+ context[prop] = change[1];
3369
3356
  }
3370
3357
  const result = parser({
3371
3358
  source,
3372
3359
  context
3373
3360
  });
3374
- if (context) for (let i = 0; i < changes.length; ++i) {
3361
+ for (let i = 0; i < changes.length; ++i) {
3375
3362
  const change = changes[i];
3376
3363
  const prop = change[0];
3377
3364
  switch (prop) {
3378
3365
  case 'resources':
3379
- // @ts-expect-error
3366
+ break;
3380
3367
  case 'memo':
3381
- if (!reset) break;
3382
- // fallthrough
3383
- default:
3384
- context[prop] = values[i];
3385
- values[i] = undefined;
3368
+ context.memo.clear();
3369
+ break;
3386
3370
  }
3371
+ context[prop] = values[i];
3372
+ values[i] = undefined;
3387
3373
  }
3388
3374
  return result;
3389
3375
  }
@@ -3407,7 +3393,7 @@ function syntax(syntax, prec, state, parser) {
3407
3393
  cache ?? memo.set(position, syntax, stateInner, (0, parser_1.eval)(result), source.length - (0, parser_1.exec)(result, '').length);
3408
3394
  }
3409
3395
  if (result && !stateOuter && memo.length >= position + 2) {
3410
- memo.clear(position + 2);
3396
+ memo.resize(position + 2);
3411
3397
  }
3412
3398
  context.state = stateOuter;
3413
3399
  return result;
@@ -3547,7 +3533,7 @@ class Delimiters {
3547
3533
  return `r/${pattern.source}/${pattern.flags}`;
3548
3534
  }
3549
3535
  }
3550
- push(...delims) {
3536
+ push(delims) {
3551
3537
  const {
3552
3538
  registry,
3553
3539
  delimiters,
@@ -3557,7 +3543,7 @@ class Delimiters {
3557
3543
  const {
3558
3544
  signature,
3559
3545
  matcher,
3560
- precedence = 1
3546
+ precedence
3561
3547
  } = delims[i];
3562
3548
  const stack = registry(signature);
3563
3549
  const index = stack[0]?.index ?? delimiters.length;
@@ -3576,7 +3562,7 @@ class Delimiters {
3576
3562
  }
3577
3563
  }
3578
3564
  }
3579
- pop(count = 1) {
3565
+ pop(count) {
3580
3566
  const {
3581
3567
  registry,
3582
3568
  delimiters,
@@ -3640,9 +3626,8 @@ Object.defineProperty(exports, "__esModule", ({
3640
3626
  }));
3641
3627
  exports.Memo = void 0;
3642
3628
  class Memo {
3643
- constructor({
3644
- targets = ~0
3645
- } = {}) {
3629
+ constructor(targets = ~0) {
3630
+ this.targets = targets;
3646
3631
  this.memory = [];
3647
3632
  this.targets = targets;
3648
3633
  }
@@ -3660,15 +3645,18 @@ class Memo {
3660
3645
  //console.log('set', position, syntax, state, record[syntax]?.[state]);
3661
3646
  }
3662
3647
 
3663
- clear(position) {
3648
+ resize(position) {
3664
3649
  const memory = this.memory;
3665
3650
  for (let len = memory.length, i = position; i < len; ++i) {
3666
3651
  memory.pop();
3667
3652
  }
3668
- //console.log('clear', position + 1);
3653
+ //console.log('resize', position + 1);
3669
3654
  }
3670
- }
3671
3655
 
3656
+ clear() {
3657
+ this.memory = [];
3658
+ }
3659
+ }
3672
3660
  exports.Memo = Memo;
3673
3661
 
3674
3662
  /***/ }),
@@ -3781,7 +3769,7 @@ function some(parser, end, delimiters = [], limit = -1) {
3781
3769
  let nodes;
3782
3770
  if (delims.length > 0) {
3783
3771
  context.delimiters ??= new delimiter_1.Delimiters();
3784
- context.delimiters.push(...delims);
3772
+ context.delimiters.push(delims);
3785
3773
  }
3786
3774
  while (true) {
3787
3775
  if (rest === '') break;
@@ -3972,7 +3960,6 @@ Object.defineProperty(exports, "__esModule", ({
3972
3960
  }));
3973
3961
  exports.bind = void 0;
3974
3962
  const parser_1 = __webpack_require__(6728);
3975
- const memo_1 = __webpack_require__(1090);
3976
3963
  const segment_1 = __webpack_require__(9002);
3977
3964
  const header_1 = __webpack_require__(5702);
3978
3965
  const block_1 = __webpack_require__(4032);
@@ -3985,12 +3972,8 @@ const array_1 = __webpack_require__(8112);
3985
3972
  function bind(target, settings) {
3986
3973
  let context = {
3987
3974
  ...settings,
3988
- host: settings.host ?? new url_1.ReadonlyURL(location.pathname, location.origin),
3989
- memo: new memo_1.Memo({
3990
- targets: 472 /* State.backtrackers */
3991
- })
3975
+ host: settings.host ?? new url_1.ReadonlyURL(location.pathname, location.origin)
3992
3976
  };
3993
-
3994
3977
  if (context.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
3995
3978
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
3996
3979
  const blocks = [];
@@ -4297,7 +4280,6 @@ Object.defineProperty(exports, "__esModule", ({
4297
4280
  }));
4298
4281
  exports.parse = void 0;
4299
4282
  const parser_1 = __webpack_require__(6728);
4300
- const memo_1 = __webpack_require__(1090);
4301
4283
  const segment_1 = __webpack_require__(9002);
4302
4284
  const header_1 = __webpack_require__(5702);
4303
4285
  const block_1 = __webpack_require__(4032);
@@ -4316,14 +4298,8 @@ function parse(source, opts = {}, context) {
4316
4298
  url: url ? new url_1.ReadonlyURL(url) : context?.url,
4317
4299
  id: opts.id ?? context?.id,
4318
4300
  caches: context?.caches,
4319
- ...(context?.resources && {
4320
- resources: context.resources
4321
- }),
4322
- memo: new memo_1.Memo({
4323
- targets: 472 /* State.backtrackers */
4324
- })
4301
+ resources: context?.resources
4325
4302
  };
4326
-
4327
4303
  if (context.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
4328
4304
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
4329
4305
  const node = (0, dom_1.frag)();
@@ -4376,6 +4352,7 @@ Object.defineProperty(exports, "__esModule", ({
4376
4352
  }));
4377
4353
  exports.block = void 0;
4378
4354
  const combinator_1 = __webpack_require__(2087);
4355
+ const memo_1 = __webpack_require__(1090);
4379
4356
  const source_1 = __webpack_require__(6743);
4380
4357
  const pagebreak_1 = __webpack_require__(4107);
4381
4358
  const heading_1 = __webpack_require__(4623);
@@ -4394,12 +4371,13 @@ const reply_1 = __webpack_require__(9978);
4394
4371
  const paragraph_1 = __webpack_require__(6457);
4395
4372
  const random_1 = __webpack_require__(7325);
4396
4373
  const dom_1 = __webpack_require__(3252);
4397
- exports.block = (0, combinator_1.creation)(0, false, error((0, combinator_1.reset)({
4374
+ exports.block = (0, combinator_1.creation)(0, false, (0, combinator_1.reset)({
4398
4375
  resources: {
4399
4376
  clock: 20000,
4400
4377
  recursion: 20 + 1
4401
- }
4402
- }, (0, combinator_1.union)([source_1.emptyline, pagebreak_1.pagebreak, heading_1.heading, ulist_1.ulist, olist_1.olist, ilist_1.ilist, dlist_1.dlist, table_1.table, codeblock_1.codeblock, mathblock_1.mathblock, extension_1.extension, sidefence_1.sidefence, blockquote_1.blockquote, mediablock_1.mediablock, reply_1.reply, paragraph_1.paragraph]))));
4378
+ },
4379
+ memo: new memo_1.Memo(472 /* State.backtrackers */)
4380
+ }, error((0, combinator_1.union)([source_1.emptyline, pagebreak_1.pagebreak, heading_1.heading, ulist_1.ulist, olist_1.olist, ilist_1.ilist, dlist_1.dlist, table_1.table, codeblock_1.codeblock, mathblock_1.mathblock, extension_1.extension, sidefence_1.sidefence, blockquote_1.blockquote, mediablock_1.mediablock, reply_1.reply, paragraph_1.paragraph]))));
4403
4381
  function error(parser) {
4404
4382
  return (0, combinator_1.recover)((0, combinator_1.fallback)((0, combinator_1.open)('\x07', ({
4405
4383
  source
@@ -5254,7 +5232,7 @@ const dom_1 = __webpack_require__(3252);
5254
5232
  exports.segment = (0, combinator_1.block)((0, combinator_1.validate)('#', (0, combinator_1.focus)(/^#+[^\S\n]+\S[^\n]*(?:\n#+(?!\S)[^\n]*)*(?:$|\n)/, (0, combinator_1.some)((0, combinator_1.line)(({
5255
5233
  source
5256
5234
  }) => [[source], ''])))));
5257
- exports.heading = (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.state)(256 /* State.annotation */ | 128 /* State.reference */ | 64 /* State.index */ | 32 /* State.label */ | 16 /* State.link */ | 8 /* State.media */, (0, combinator_1.line)((0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.union)([(0, combinator_1.open)((0, source_1.str)(/^##+/), (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline])))), true), (0, combinator_1.open)((0, source_1.str)('#'), (0, combinator_1.state)(2 /* State.autolink */, (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline]))))), true)]), ([h, ...ns]) => [h.length <= 6 ? (0, dom_1.html)(`h${h.length}`, (0, visibility_1.trimNodeEnd)((0, dom_1.defrag)(ns))) : (0, dom_1.html)(`h6`, {
5235
+ exports.heading = (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.state)(256 /* State.annotation */ | 128 /* State.reference */ | 64 /* State.index */ | 32 /* State.label */ | 16 /* State.link */ | 8 /* State.media */, (0, combinator_1.line)((0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.union)([(0, combinator_1.open)((0, source_1.str)(/^##+/), (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline])))), true), (0, combinator_1.open)((0, source_1.str)('#'), (0, combinator_1.state)(502 /* State.linkers */, (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline]))))), true)]), ([h, ...ns]) => [h.length <= 6 ? (0, dom_1.html)(`h${h.length}`, (0, visibility_1.trimNodeEnd)((0, dom_1.defrag)(ns))) : (0, dom_1.html)(`h6`, {
5258
5236
  class: 'invalid',
5259
5237
  'data-invalid-syntax': 'heading',
5260
5238
  'data-invalid-type': 'syntax',
@@ -5586,7 +5564,6 @@ Object.defineProperty(exports, "__esModule", ({
5586
5564
  value: true
5587
5565
  }));
5588
5566
  exports.quote = exports.syntax = void 0;
5589
- const parser_1 = __webpack_require__(6728);
5590
5567
  const combinator_1 = __webpack_require__(2087);
5591
5568
  const math_1 = __webpack_require__(8946);
5592
5569
  const autolink_1 = __webpack_require__(6051);
@@ -5601,42 +5578,7 @@ exports.quote = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, false
5601
5578
  'data-invalid-type': 'syntax',
5602
5579
  'data-invalid-message': `Missing the whitespace after "${ns[0].split(/[^>]/, 1)[0]}"`
5603
5580
  }, (0, dom_1.defrag)(ns)), (0, dom_1.html)('br')]), false)));
5604
- const qblock = ({
5605
- source,
5606
- context
5607
- }) => {
5608
- source = source.replace(/\n$/, '');
5609
- const lines = source.match(/^.*\n?/mg);
5610
- const quotes = source.match(/^>+[^\S\n]/mg);
5611
- const content = lines.reduce((acc, line, i) => acc + line.slice(quotes[i].length), '');
5612
- const nodes = (0, parser_1.eval)(text({
5613
- source: `\r${content}`,
5614
- context
5615
- }), []);
5616
- nodes.unshift(quotes.shift());
5617
- for (let i = 0; i < nodes.length; ++i) {
5618
- const child = nodes[i];
5619
- if (typeof child === 'string') continue;
5620
- if ('wholeText' in child) {
5621
- nodes[i] = child.data;
5622
- continue;
5623
- }
5624
- if (child.tagName === 'BR') {
5625
- nodes.splice(i + 1, 0, quotes.shift());
5626
- ++i;
5627
- continue;
5628
- }
5629
- if (child.className === 'cite' || child.classList.contains('quote')) {
5630
- context.resources && (context.resources.clock -= child.childNodes.length);
5631
- nodes.splice(i, 1, ...child.childNodes);
5632
- --i;
5633
- continue;
5634
- }
5635
- }
5636
- nodes.unshift('');
5637
- return [nodes, ''];
5638
- };
5639
- const text = (0, combinator_1.some)((0, combinator_1.union)([math_1.math, autolink_1.autolink, source_1.linebreak, source_1.unescsource]));
5581
+ const qblock = (0, combinator_1.convert)(source => source.replace(/\n$/, '').replace(/(?<=^>+[^\S\n])/mg, '\r'), (0, combinator_1.some)((0, combinator_1.union)([math_1.math, autolink_1.autolink, source_1.linebreak, source_1.unescsource])));
5640
5582
 
5641
5583
  /***/ }),
5642
5584
 
@@ -6120,7 +6062,7 @@ exports.bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, comb
6120
6062
  class: 'paren'
6121
6063
  }, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 2, 0 /* State.none */, (0, source_1.str)(new RegExp(index.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => c.trimStart() && String.fromCharCode(c.charCodeAt(0) + 0xFEE0)))))), (0, source_1.str)(')')), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, ')', [[/^\\?\n/, 3], [')', 2]]))), (0, source_1.str)(')'), true, ([as, bs = [], cs], rest) => [[(0, dom_1.html)('span', {
6122
6064
  class: 'paren'
6123
- }, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, ']', [[/^\\?\n/, 3], [']', 2]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '"', [[/^\\?\n/, 4], ['"', 3]]))), (0, source_1.str)('"'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest])]));
6065
+ }, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, ']', [[/^\\?\n/, 3], [']', 2]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, ']', [[/^\\?\n/, 3], [']', 2]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '"', [[/^\\?\n/, 4], ['"', 3]]))), (0, source_1.str)('"'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('“'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '”', [[/^\\?\n/, 4], ['”', 3]]))), (0, source_1.str)('”'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('‘'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '’', [[/^\\?\n/, 4], ['’', 3]]))), (0, source_1.str)('’'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('「'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '」', [[/^\\?\n/, 4], ['」', 3]]))), (0, source_1.str)('」'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('『'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '』', [[/^\\?\n/, 4], ['』', 3]]))), (0, source_1.str)('』'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest])]));
6124
6066
 
6125
6067
  /***/ }),
6126
6068
 
@@ -7618,7 +7560,7 @@ exports.isAlphanumeric = exports.linebreak = exports.txt = exports.text = export
7618
7560
  const combinator_1 = __webpack_require__(2087);
7619
7561
  const str_1 = __webpack_require__(2790);
7620
7562
  const dom_1 = __webpack_require__(3252);
7621
- exports.delimiter = /[\s\x00-\x7F()]|\S[#>]/u;
7563
+ exports.delimiter = /[\s\x00-\x7F()[]{}“”‘’「」『』]|\S[#>]/u;
7622
7564
  exports.nonWhitespace = /[\S\n]|$/u;
7623
7565
  exports.nonAlphanumeric = /[^0-9A-Za-z]|\S[#>]|$/u;
7624
7566
  const repeat = (0, str_1.str)(/^(.)\1*/);
@@ -8564,7 +8506,7 @@ function level(h) {
8564
8506
  function unlink(h) {
8565
8507
  for (let es = h.getElementsByTagName('a'), len = es.length, i = 0; i < len; ++i) {
8566
8508
  const el = es[i];
8567
- el.replaceWith(...el.childNodes);
8509
+ el.firstChild ? el.replaceWith(el.firstChild) : el.remove();
8568
8510
  }
8569
8511
  return h.childNodes;
8570
8512
  }
package/markdown.d.ts CHANGED
@@ -631,12 +631,6 @@ export namespace MarkdownParser {
631
631
  export namespace QuoteParser {
632
632
  export interface BlockParser extends
633
633
  Block<'reply/quote/block'>,
634
- Parser<string | HTMLElement, Context, [
635
- TextParser,
636
- ]> {
637
- }
638
- export interface TextParser extends
639
- Block<'reply/quote/text'>,
640
634
  Parser<string | HTMLElement, Context, [
641
635
  InlineParser.MathParser,
642
636
  InlineParser.AutolinkParser,
@@ -1252,6 +1246,12 @@ export namespace MarkdownParser {
1252
1246
  InlineParser,
1253
1247
  InlineParser,
1254
1248
  InlineParser,
1249
+ InlineParser,
1250
+ InlineParser,
1251
+ InlineParser,
1252
+ InlineParser,
1253
+ InlineParser,
1254
+ InlineParser,
1255
1255
  ]> {
1256
1256
  }
1257
1257
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.280.0",
3
+ "version": "0.280.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,15 +34,15 @@ export class Delimiters {
34
34
  private readonly delimiters: Delimiter[] = [];
35
35
  private readonly order: number[] = [];
36
36
  public push(
37
- ...delims: readonly {
37
+ delims: readonly {
38
38
  readonly signature: string;
39
39
  readonly matcher: (source: string) => boolean | undefined;
40
- readonly precedence?: number;
40
+ readonly precedence: number;
41
41
  }[]
42
42
  ): void {
43
43
  const { registry, delimiters, order } = this;
44
44
  for (let i = 0; i < delims.length; ++i) {
45
- const { signature, matcher, precedence = 1 } = delims[i];
45
+ const { signature, matcher, precedence } = delims[i];
46
46
  const stack = registry(signature);
47
47
  const index = stack[0]?.index ?? delimiters.length;
48
48
  if (stack.length === 0 || precedence > delimiters[index].precedence) {
@@ -61,7 +61,7 @@ export class Delimiters {
61
61
  }
62
62
  }
63
63
  }
64
- public pop(count = 1): void {
64
+ public pop(count: number): void {
65
65
  assert(count > 0);
66
66
  const { registry, delimiters, order } = this;
67
67
  for (let i = 0; i < count; ++i) {
@@ -1,9 +1,10 @@
1
1
  export class Memo {
2
- constructor({ targets = ~0 } = {}) {
2
+ constructor(
3
+ public readonly targets = ~0,
4
+ ) {
3
5
  this.targets = targets;
4
6
  }
5
- public readonly targets: number;
6
- private readonly memory: Record<number, Record<number, readonly [any[], number] | readonly []>>[/* pos */] = [];
7
+ private memory: Record<number, Record<number, readonly [any[], number] | readonly []>>[/* pos */] = [];
7
8
  public get length(): number {
8
9
  return this.memory.length;
9
10
  }
@@ -32,11 +33,14 @@ export class Memo {
32
33
  : [];
33
34
  //console.log('set', position, syntax, state, record[syntax]?.[state]);
34
35
  }
35
- public clear(position: number): void {
36
+ public resize(position: number): void {
36
37
  const memory = this.memory;
37
38
  for (let len = memory.length, i = position; i < len; ++i) {
38
39
  memory.pop();
39
40
  }
40
- //console.log('clear', position + 1);
41
+ //console.log('resize', position + 1);
42
+ }
43
+ public clear(): void {
44
+ this.memory = [];
41
45
  }
42
46
  }
@@ -1,12 +1,9 @@
1
- import { hasOwnProperty, ObjectCreate } from 'spica/alias';
1
+ import { ObjectCreate } from 'spica/alias';
2
2
  import { Parser, Result, Ctx, Tree, Context, eval, exec } from '../../data/parser';
3
3
  import { Memo } from './context/memo';
4
4
 
5
5
  export function reset<P extends Parser<unknown>>(base: Context<P>, parser: P): P;
6
6
  export function reset<T>(base: Ctx, parser: Parser<T>): Parser<T> {
7
- if (!('memo' in base)) {
8
- base.memo = undefined;
9
- }
10
7
  assert(Object.getPrototypeOf(base) === Object.prototype);
11
8
  assert(Object.freeze(base));
12
9
  const changes = Object.entries(base);
@@ -27,41 +24,38 @@ export function context<T>(base: Ctx, parser: Parser<T>): Parser<T> {
27
24
 
28
25
  function apply<P extends Parser<unknown>>(parser: P, source: string, context: Context<P>, changes: readonly [string, unknown][], values: unknown[], reset?: boolean): Result<Tree<P>>;
29
26
  function apply<T>(parser: Parser<T>, source: string, context: Ctx, changes: readonly [string, unknown][], values: unknown[], reset = false): Result<T> {
30
- if (context) for (let i = 0; i < changes.length; ++i) {
27
+ for (let i = 0; i < changes.length; ++i) {
31
28
  const change = changes[i];
32
29
  const prop = change[0];
33
30
  switch (prop) {
34
31
  case 'resources':
35
- if (!reset) break;
36
- assert(typeof change[1] === 'object');
37
- assert(context[prop] || !(prop in context));
38
- if (prop in context && !hasOwnProperty(context, prop)) break;
39
- context[prop as string] = ObjectCreate(change[1] as object);
40
- break;
41
- // @ts-expect-error
42
- case 'memo':
43
- if (!reset) break;
44
- context.memo = new Memo({ targets: context.memo?.targets });
45
- // fallthrough
46
- default:
47
- values[i] = context[prop];
48
- context[prop] = change[1];
32
+ assert(reset);
33
+ assert(!context.offset);
34
+ assert(!context.precedence);
35
+ assert(!context.delimiters);
36
+ assert(!context.state);
37
+ assert(!context.memo);
38
+ context[prop as string] ??= ObjectCreate(change[1] as object);
39
+ continue;
49
40
  }
41
+ values[i] = context[prop];
42
+ context[prop] = change[1];
50
43
  }
51
44
  const result = parser({ source, context });
52
- if (context) for (let i = 0; i < changes.length; ++i) {
45
+ for (let i = 0; i < changes.length; ++i) {
53
46
  const change = changes[i];
54
47
  const prop = change[0];
55
48
  switch (prop) {
56
49
  case 'resources':
57
- // @ts-expect-error
50
+ assert(reset);
51
+ break;
58
52
  case 'memo':
59
- if (!reset) break;
60
- // fallthrough
61
- default:
62
- context[prop] = values[i];
63
- values[i] = undefined;
53
+ assert(reset);
54
+ context.memo!.clear();
55
+ break;
64
56
  }
57
+ context[prop] = values[i];
58
+ values[i] = undefined;
65
59
  }
66
60
  return result;
67
61
  }
@@ -87,7 +81,7 @@ export function syntax<T>(syntax: number, prec: number, state: number, parser?:
87
81
  }
88
82
  if (result && !stateOuter && memo.length! >= position + 2) {
89
83
  assert(!(stateOuter & memo.targets));
90
- memo.clear(position + 2);
84
+ memo.resize(position + 2);
91
85
  }
92
86
  context.state = stateOuter;
93
87
  return result;
@@ -22,7 +22,7 @@ export function some<T>(parser: Parser<T>, end?: string | RegExp | number, delim
22
22
  let nodes: T[] | undefined;
23
23
  if (delims.length > 0) {
24
24
  context.delimiters ??= new Delimiters();
25
- context.delimiters.push(...delims);
25
+ context.delimiters.push(delims);
26
26
  }
27
27
  while (true) {
28
28
  if (rest === '') break;
@@ -1,11 +1,9 @@
1
1
  import { ParserSettings, Progress } from '../../..';
2
2
  import { MarkdownParser } from '../../../markdown';
3
3
  import { eval } from '../../combinator/data/parser';
4
- import { Memo } from '../../combinator/data/parser/context/memo';
5
4
  import { segment, validate, MAX_INPUT_SIZE } from '../segment';
6
5
  import { header } from '../header';
7
6
  import { block } from '../block';
8
- import { State } from '../context';
9
7
  import { normalize } from './normalize';
10
8
  import { headers } from './header';
11
9
  import { figure } from '../processor/figure';
@@ -24,11 +22,14 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
24
22
  let context: MarkdownParser.Context = {
25
23
  ...settings,
26
24
  host: settings.host ?? new ReadonlyURL(location.pathname, location.origin),
27
- memo: new Memo({ targets: State.backtrackers }),
28
25
  };
26
+ assert(!context.offset);
27
+ assert(!context.precedence);
28
+ assert(!context.delimiters);
29
+ assert(!context.state);
30
+ assert(!context.memo);
29
31
  if (context.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
30
32
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
31
- assert(!settings.id);
32
33
  type Block = readonly [segment: string, blocks: readonly HTMLElement[], url: string];
33
34
  const blocks: Block[] = [];
34
35
  const adds: [HTMLElement, Node | null][] = [];
@@ -333,7 +333,6 @@ describe('Unit: parser/api/parse', () => {
333
333
 
334
334
  it('creation', function () {
335
335
  this.timeout(5000);
336
- // 実測500ms程度
337
336
  assert.deepStrictEqual(
338
337
  [...parse('.'.repeat(20000)).children].map(el => el.outerHTML),
339
338
  [`<p>${'.'.repeat(20000)}</p>`]);
@@ -341,7 +340,6 @@ describe('Unit: parser/api/parse', () => {
341
340
 
342
341
  it('creation error', function () {
343
342
  this.timeout(5000);
344
- // 実測500ms程度
345
343
  assert.deepStrictEqual(
346
344
  [...parse('.'.repeat(20001)).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
347
345
  [
@@ -350,6 +348,16 @@ describe('Unit: parser/api/parse', () => {
350
348
  ]);
351
349
  });
352
350
 
351
+ it('recovery', function () {
352
+ this.timeout(5000);
353
+ assert.deepStrictEqual(
354
+ [...parse(`!>> ${'['.repeat(20)}${'{a}'.repeat(518)}\n> ${'{a}'.repeat(4)}\n\na`).children].map(el => el.outerHTML),
355
+ [
356
+ `<blockquote><blockquote><section><p>${'['.repeat(20)}${'<a class="url" href="a">a</a>'.repeat(518)}</p><h2>References</h2><ol class="references"></ol></section></blockquote><section><h1 class="error">Error: Too many creations</h1><pre class="error" translate="no">{a}{a}{a}{a}</pre><h2>References</h2><ol class="references"></ol></section></blockquote>`,
357
+ '<p>a</p>',
358
+ ]);
359
+ });
360
+
353
361
  });
354
362
 
355
363
  });
@@ -1,11 +1,9 @@
1
1
  import { ParserOptions } from '../../..';
2
2
  import { MarkdownParser } from '../../../markdown';
3
3
  import { eval } from '../../combinator/data/parser';
4
- import { Memo } from '../../combinator/data/parser/context/memo';
5
4
  import { segment, validate, MAX_SEGMENT_SIZE } from '../segment';
6
5
  import { header } from '../header';
7
6
  import { block } from '../block';
8
- import { State } from '../context';
9
7
  import { normalize } from './normalize';
10
8
  import { headers } from './header';
11
9
  import { figure } from '../processor/figure';
@@ -21,17 +19,18 @@ export function parse(source: string, opts: Options = {}, context?: MarkdownPars
21
19
  if (!validate(source, MAX_SEGMENT_SIZE)) throw new Error(`Too large input over ${MAX_SEGMENT_SIZE.toLocaleString('en')} bytes`);
22
20
  const url = headers(source).find(field => field.toLowerCase().startsWith('url:'))?.slice(4).trim() ?? '';
23
21
  source = !context ? normalize(source) : source;
24
- assert(!context?.delimiters);
25
22
  context = {
26
23
  host: opts.host ?? context?.host ?? new ReadonlyURL(location.pathname, location.origin),
27
24
  url: url ? new ReadonlyURL(url as ':') : context?.url,
28
25
  id: opts.id ?? context?.id,
29
26
  caches: context?.caches,
30
- ...context?.resources && {
31
- resources: context.resources,
32
- },
33
- memo: new Memo({ targets: State.backtrackers }),
27
+ resources: context?.resources,
34
28
  };
29
+ assert(!context.offset);
30
+ assert(!context.precedence);
31
+ assert(!context.delimiters);
32
+ assert(!context.state);
33
+ assert(!context.memo);
35
34
  if (context.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
36
35
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
37
36
  const node = frag();
@@ -18,7 +18,7 @@ export const heading: HeadingParser = block(rewrite(segment,
18
18
  visualize(trimBlankStart(some(union([indexer, inline])))), true),
19
19
  open(
20
20
  str('#'),
21
- state(State.autolink,
21
+ state(State.linkers,
22
22
  visualize(trimBlankStart(some(union([indexer, inline]))))), true),
23
23
  ]),
24
24
  ([h, ...ns]: [string, ...(HTMLElement | string)[]]) => [
@@ -1,6 +1,5 @@
1
1
  import { ReplyParser } from '../../block';
2
- import { eval } from '../../../combinator/data/parser';
3
- import { union, some, creation, block, line, validate, rewrite, lazy, fmap } from '../../../combinator';
2
+ import { union, some, creation, block, line, validate, rewrite, convert, lazy, fmap } from '../../../combinator';
4
3
  import { math } from '../../inline/math';
5
4
  import { autolink } from '../../inline/autolink';
6
5
  import { linebreak, unescsource, str, anyline } from '../../source';
@@ -33,47 +32,11 @@ export const quote: ReplyParser.QuoteParser = lazy(() => creation(1, false, bloc
33
32
  ]),
34
33
  false)));
35
34
 
36
- const qblock: ReplyParser.QuoteParser.BlockParser = ({ source, context }) => {
37
- source = source.replace(/\n$/, '');
38
- const lines = source.match(/^.*\n?/mg)!;
39
- assert(lines);
40
- const quotes = source.match(/^>+[^\S\n]/mg)!;
41
- assert(quotes);
42
- assert(quotes.length > 0);
43
- const content = lines.reduce((acc, line, i) => acc + line.slice(quotes[i].length), '');
44
- const nodes = eval(text({ source: `\r${content}`, context }), []);
45
- nodes.unshift(quotes.shift()!);
46
- for (let i = 0; i < nodes.length; ++i) {
47
- const child = nodes[i] as string | Text | Element;
48
- if (typeof child === 'string') continue;
49
- if ('wholeText' in child) {
50
- nodes[i] = child.data;
51
- continue;
52
- }
53
- assert(child instanceof HTMLElement);
54
- if (child.tagName === 'BR') {
55
- assert(quotes.length > 0);
56
- nodes.splice(i + 1, 0, quotes.shift()!);
57
- ++i;
58
- continue;
59
- }
60
- if (child.className === 'cite' || child.classList.contains('quote')) {
61
- context.resources && (context.resources.clock -= child.childNodes.length);
62
- nodes.splice(i, 1, ...child.childNodes as NodeListOf<HTMLElement>);
63
- --i;
64
- continue;
65
- }
66
- }
67
- nodes.unshift('');
68
- assert(nodes.length > 1);
69
- assert(nodes.every(n => typeof n === 'string' || n instanceof HTMLElement));
70
- assert(quotes.length === 0);
71
- return [nodes, ''];
72
- };
73
-
74
- const text: ReplyParser.QuoteParser.TextParser = some(union([
75
- math, // quote補助関数が残した数式をパースする。他の構文で数式を残す場合はソーステキストを直接使用する。
76
- autolink,
77
- linebreak,
78
- unescsource,
79
- ]));
35
+ const qblock: ReplyParser.QuoteParser.BlockParser = convert(
36
+ source => source.replace(/\n$/, '').replace(/(?<=^>+[^\S\n])/mg, '\r'),
37
+ some(union([
38
+ math, // quote補助関数が残した数式をパースする。他の構文で数式を残す場合はソーステキストを直接使用する。
39
+ autolink,
40
+ linebreak,
41
+ unescsource,
42
+ ])));
@@ -1,5 +1,6 @@
1
1
  import { MarkdownParser } from '../../markdown';
2
2
  import { union, reset, creation, open, fallback, recover } from '../combinator';
3
+ import { Memo } from '../combinator/data/parser/context/memo';
3
4
  import { emptyline } from './source';
4
5
  import { pagebreak } from './block/pagebreak';
5
6
  import { heading } from './block/heading';
@@ -16,6 +17,7 @@ import { blockquote } from './block/blockquote';
16
17
  import { mediablock } from './block/mediablock';
17
18
  import { reply } from './block/reply';
18
19
  import { paragraph } from './block/paragraph';
20
+ import { State } from './context';
19
21
  import { rnd0Z } from 'spica/random';
20
22
  import { html } from 'typed-dom/dom';
21
23
 
@@ -36,9 +38,9 @@ export import MediaBlockParser = BlockParser.MediaBlockParser;
36
38
  export import ReplyParser = BlockParser.ReplyParser;
37
39
  export import ParagraphParser = BlockParser.ParagraphParser;
38
40
 
39
- export const block: BlockParser = creation(0, false, error(
40
- reset({ resources: { clock: 20000, recursion: 20 + 1 } },
41
- union([
41
+ export const block: BlockParser = creation(0, false,
42
+ reset({ resources: { clock: 20000, recursion: 20 + 1 }, memo: new Memo(State.backtrackers) },
43
+ error(union([
42
44
  emptyline,
43
45
  pagebreak,
44
46
  heading,
@@ -20,10 +20,28 @@ export const bracket: BracketParser = lazy(() => union([
20
20
  surround(str('['), creation(syntax(Syntax.bracket, 2, State.none, some(inline, ']', [[/^\\?\n/, 3], [']', 2]]))), str(']'), true,
21
21
  undefined,
22
22
  ([as, bs = []], rest) => [unshift(as, bs), rest]),
23
+ surround(str('['), creation(syntax(Syntax.bracket, 2, State.none, some(inline, ']', [[/^\\?\n/, 3], [']', 2]]))), str(']'), true,
24
+ undefined,
25
+ ([as, bs = []], rest) => [unshift(as, bs), rest]),
23
26
  surround(str('{'), creation(syntax(Syntax.bracket, 2, State.none, some(inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), str('}'), true,
24
27
  undefined,
25
28
  ([as, bs = []], rest) => [unshift(as, bs), rest]),
29
+ surround(str('{'), creation(syntax(Syntax.bracket, 2, State.none, some(inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), str('}'), true,
30
+ undefined,
31
+ ([as, bs = []], rest) => [unshift(as, bs), rest]),
26
32
  surround(str('"'), creation(syntax(Syntax.none, 3, State.none, some(inline, '"', [[/^\\?\n/, 4], ['"', 3]]))), str('"'), true,
27
33
  undefined,
28
34
  ([as, bs = []], rest) => [unshift(as, bs), rest]),
35
+ surround(str('“'), creation(syntax(Syntax.none, 3, State.none, some(inline, '”', [[/^\\?\n/, 4], ['”', 3]]))), str('”'), true,
36
+ undefined,
37
+ ([as, bs = []], rest) => [unshift(as, bs), rest]),
38
+ surround(str('‘'), creation(syntax(Syntax.none, 3, State.none, some(inline, '’', [[/^\\?\n/, 4], ['’', 3]]))), str('’'), true,
39
+ undefined,
40
+ ([as, bs = []], rest) => [unshift(as, bs), rest]),
41
+ surround(str('「'), creation(syntax(Syntax.none, 3, State.none, some(inline, '」', [[/^\\?\n/, 4], ['」', 3]]))), str('」'), true,
42
+ undefined,
43
+ ([as, bs = []], rest) => [unshift(as, bs), rest]),
44
+ surround(str('『'), creation(syntax(Syntax.none, 3, State.none, some(inline, '』', [[/^\\?\n/, 4], ['』', 3]]))), str('』'), true,
45
+ undefined,
46
+ ([as, bs = []], rest) => [unshift(as, bs), rest]),
29
47
  ]));
@@ -3,7 +3,7 @@ import { union, creation, focus } from '../../combinator';
3
3
  import { str } from './str';
4
4
  import { html } from 'typed-dom/dom';
5
5
 
6
- export const delimiter = /[\s\x00-\x7F()]|\S[#>]/u;
6
+ export const delimiter = /[\s\x00-\x7F()[]{}“”‘’「」『』]|\S[#>]/u;
7
7
  export const nonWhitespace = /[\S\n]|$/u;
8
8
  export const nonAlphanumeric = /[^0-9A-Za-z]|\S[#>]|$/u;
9
9
  const repeat = str(/^(.)\1*/);
package/src/util/toc.ts CHANGED
@@ -61,7 +61,10 @@ function level(h: HTMLHeadingElement): number {
61
61
  function unlink(h: HTMLHeadingElement): Iterable<Node> {
62
62
  for (let es = h.getElementsByTagName('a'), len = es.length, i = 0; i < len; ++i) {
63
63
  const el = es[i];
64
- el.replaceWith(...el.childNodes);
64
+ assert(el.childNodes.length <= 1);
65
+ el.firstChild
66
+ ? el.replaceWith(el.firstChild)
67
+ : el.remove();
65
68
  }
66
69
  return h.childNodes;
67
70
  }