securemark 0.293.3 → 0.293.5

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/index.js +125 -141
  3. package/package.json +1 -1
  4. package/src/combinator/control/manipulation/surround.ts +2 -2
  5. package/src/combinator/data/parser/context.test.ts +10 -9
  6. package/src/combinator/data/parser/context.ts +2 -1
  7. package/src/combinator/data/parser.ts +0 -3
  8. package/src/parser/api/bind.ts +3 -3
  9. package/src/parser/api/normalize.ts +1 -3
  10. package/src/parser/api/parse.ts +1 -1
  11. package/src/parser/block/dlist.test.ts +1 -1
  12. package/src/parser/block/heading.test.ts +1 -0
  13. package/src/parser/block/olist.test.ts +1 -0
  14. package/src/parser/block/reply/quote.ts +6 -6
  15. package/src/parser/block/reply.ts +3 -2
  16. package/src/parser/block/ulist.test.ts +1 -0
  17. package/src/parser/header.test.ts +3 -1
  18. package/src/parser/header.ts +2 -2
  19. package/src/parser/inline/emphasis.test.ts +1 -0
  20. package/src/parser/inline/html.test.ts +3 -3
  21. package/src/parser/inline/html.ts +9 -9
  22. package/src/parser/inline/italic.test.ts +1 -0
  23. package/src/parser/inline/link.test.ts +10 -8
  24. package/src/parser/inline/link.ts +17 -17
  25. package/src/parser/inline/mark.test.ts +1 -0
  26. package/src/parser/inline/media.test.ts +6 -7
  27. package/src/parser/inline/media.ts +3 -3
  28. package/src/parser/inline/remark.test.ts +3 -1
  29. package/src/parser/inline/strong.test.ts +1 -0
  30. package/src/parser/source/escapable.test.ts +1 -0
  31. package/src/parser/source/escapable.ts +3 -11
  32. package/src/parser/source/text.test.ts +5 -4
  33. package/src/parser/source/text.ts +90 -94
  34. package/src/parser/source/unescapable.test.ts +1 -0
  35. package/src/parser/source/unescapable.ts +5 -8
  36. package/src/parser/util.ts +0 -19
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.293.5
4
+
5
+ - Refactoring.
6
+
7
+ ## 0.293.4
8
+
9
+ - Refactoring.
10
+
3
11
  ## 0.293.3
4
12
 
5
13
  - Refactoring.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.293.3 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.293.5 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"));
@@ -3073,11 +3073,10 @@ function isBacktrack(context, backtracks, position = context.position, length =
3073
3073
  }
3074
3074
  exports.isBacktrack = isBacktrack;
3075
3075
  function setBacktrack(context, backtracks, position, length = 1) {
3076
+ // 以降バックトラックの可能性がなく記録不要の場合もあるが判別が面倒なので省略
3076
3077
  const {
3077
- source,
3078
- state = 0
3078
+ source
3079
3079
  } = context;
3080
- if (state === 0) return;
3081
3080
  if (position === source.length) return;
3082
3081
  if (length === 0) return;
3083
3082
  for (const backtrack of backtracks) {
@@ -3250,7 +3249,11 @@ function reset(base, parser) {
3250
3249
  const values = Array(changes.length);
3251
3250
  return ({
3252
3251
  context
3253
- }) => apply(parser, context, changes, values, true);
3252
+ }) =>
3253
+ // 大域離脱時の汚染回避のため複製
3254
+ apply(parser, {
3255
+ ...context
3256
+ }, changes, values, true);
3254
3257
  }
3255
3258
  exports.reset = reset;
3256
3259
  function context(base, parser) {
@@ -3917,7 +3920,7 @@ function bind(target, settings) {
3917
3920
  function* parse(source) {
3918
3921
  if (settings.chunk && revision) throw new Error('Chunks cannot be updated');
3919
3922
  const url = (0, header_2.headers)(source).find(field => field.toLowerCase().startsWith('url:'))?.slice(4).trim() ?? '';
3920
- source = (0, normalize_1.normalize)((0, segment_1.validate)(source, segment_1.MAX_INPUT_SIZE) ? source : source.slice(0, segment_1.MAX_INPUT_SIZE + 1));
3923
+ source = (0, normalize_1.normalize)(source);
3921
3924
  // Change the object identity.
3922
3925
  context = {
3923
3926
  ...context,
@@ -4165,7 +4168,7 @@ function sanitize(source) {
4165
4168
  exports.invisibleHTMLEntityNames = ['Tab', 'NewLine', 'NonBreakingSpace', 'nbsp', 'shy', 'ensp', 'emsp', 'emsp13', 'emsp14', 'numsp', 'puncsp', 'ThinSpace', 'thinsp', 'VeryThinSpace', 'hairsp', 'ZeroWidthSpace', 'NegativeVeryThinSpace', 'NegativeThinSpace', 'NegativeMediumSpace', 'NegativeThickSpace', 'zwj', 'zwnj', 'lrm', 'rlm', 'MediumSpace', 'NoBreak', 'ApplyFunction', 'af', 'InvisibleTimes', 'it', 'InvisibleComma', 'ic'];
4166
4169
  const unreadableHTMLEntityNames = exports.invisibleHTMLEntityNames.slice(2);
4167
4170
  const unreadableEscapableCharacters = unreadableHTMLEntityNames.map(name => (0, parser_1.eval)((0, htmlentity_1.unsafehtmlentity)((0, parser_1.input)(`&${name};`, {})))[0]);
4168
- const unreadableEscapableCharacter = new RegExp(`[${[...new Set(unreadableEscapableCharacters)].join('')}]`, 'g');
4171
+ const unreadableEscapableCharacter = new RegExp(`[${unreadableEscapableCharacters.join('')}]`, 'g');
4169
4172
  // https://www.pandanoir.info/entry/2018/03/11/193000
4170
4173
  // http://anti.rosx.net/etc/memo/002_space.html
4171
4174
  // http://nicowiki.com/%E7%A9%BA%E7%99%BD%E3%83%BB%E7%89%B9%E6%AE%8A%E8%A8%98%E5%8F%B7.html
@@ -5447,11 +5450,14 @@ const cite_1 = __webpack_require__(1200);
5447
5450
  const quote_1 = __webpack_require__(4847);
5448
5451
  const inline_1 = __webpack_require__(7973);
5449
5452
  const source_1 = __webpack_require__(8745);
5450
- const util_1 = __webpack_require__(4992);
5451
5453
  const visibility_1 = __webpack_require__(6364);
5454
+ const array_1 = __webpack_require__(6876);
5452
5455
  const dom_1 = __webpack_require__(394);
5453
5456
  const delimiter = new RegExp(`${cite_1.syntax.source}|${quote_1.syntax.source}`, 'y');
5454
- exports.reply = (0, combinator_1.block)((0, combinator_1.validate)(cite_1.syntax, (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.union)([cite_1.cite, quote_1.quote, (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.anyline, delimiter), (0, visibility_1.visualize)((0, util_1.linearize)((0, combinator_1.some)(inline_1.inline), 1)))])), ns => [(0, dom_1.html)('p', (0, visibility_1.trimBlankNodeEnd)((0, dom_1.defrag)(ns)))])));
5457
+ exports.reply = (0, combinator_1.block)((0, combinator_1.validate)(cite_1.syntax, (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.union)([cite_1.cite, quote_1.quote, (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.anyline, delimiter), (0, visibility_1.visualize)((0, combinator_1.fmap)((0, combinator_1.some)(inline_1.inline), (ns, {
5458
+ source,
5459
+ position
5460
+ }) => source[position - 1] === '\n' ? ns : (0, array_1.push)(ns, [(0, dom_1.html)('br')]))))])), ns => [(0, dom_1.html)('p', (0, visibility_1.trimBlankNodeEnd)((0, dom_1.defrag)(ns)))])));
5455
5461
 
5456
5462
  /***/ },
5457
5463
 
@@ -5517,14 +5523,18 @@ const combinator_1 = __webpack_require__(3484);
5517
5523
  const math_1 = __webpack_require__(2962);
5518
5524
  const autolink_1 = __webpack_require__(8072);
5519
5525
  const source_1 = __webpack_require__(8745);
5520
- const util_1 = __webpack_require__(4992);
5521
5526
  const dom_1 = __webpack_require__(394);
5522
5527
  exports.syntax = />+[^\S\n]/y;
5523
- exports.quote = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.some)((0, combinator_1.validate)(exports.syntax, source_1.anyline)), (0, util_1.linearize)((0, combinator_1.convert)(source => source.replace(/(?<=^>+[^\S\n])/mg, '\r'), (0, combinator_1.some)((0, combinator_1.union)([
5528
+ exports.quote = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.some)((0, combinator_1.validate)(exports.syntax, source_1.anyline)), (0, combinator_1.convert)(
5529
+ // TODO: インデント数を渡してインデント数前の行頭確認を行う実装に置き換える
5530
+ source => source.replace(/(?<=^>+[^\S\n])/mg, '\r'), (0, combinator_1.some)((0, combinator_1.union)([
5524
5531
  // quote補助関数が残した数式をパースする。
5525
- math_1.math, autolink_1.autolink, source_1.linebreak, source_1.unescsource])), false), -1)), ns => [(0, dom_1.html)('span', {
5532
+ math_1.math, autolink_1.autolink, source_1.linebreak, source_1.unescsource])), false)), (ns, {
5533
+ source,
5534
+ position
5535
+ }) => [source[position - 1] === '\n' ? ns.pop() : (0, dom_1.html)('br'), (0, dom_1.html)('span', {
5526
5536
  class: 'quote'
5527
- }, (0, dom_1.defrag)(ns)), (0, dom_1.html)('br')]), false));
5537
+ }, (0, dom_1.defrag)(ns))].reverse()), false));
5528
5538
 
5529
5539
  /***/ },
5530
5540
 
@@ -5665,7 +5675,7 @@ const source_1 = __webpack_require__(8745);
5665
5675
  const util_1 = __webpack_require__(4992);
5666
5676
  const normalize_1 = __webpack_require__(4490);
5667
5677
  const dom_1 = __webpack_require__(394);
5668
- exports.header = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/---+[^\S\v\f\r\n]*\r?\n[^\S\n]*(?=\S)/y, (0, combinator_1.inits)([(0, combinator_1.rewrite)(({
5678
+ exports.header = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/---+[^\S\v\f\r\n]*\r?\n(?=\S)/y, (0, combinator_1.inits)([(0, combinator_1.rewrite)(({
5669
5679
  context
5670
5680
  }) => {
5671
5681
  const {
@@ -5679,7 +5689,7 @@ exports.header = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/---+[^
5679
5689
  return [[]];
5680
5690
  }, (0, combinator_1.block)((0, combinator_1.union)([(0, combinator_1.validate)(({
5681
5691
  context
5682
- }) => context.header ?? true, (0, combinator_1.focus)(/---[^\S\v\f\r\n]*\r?\n(?:[A-Za-z][0-9A-Za-z]*(?:-[A-Za-z][0-9A-Za-z]*)*:[ \t]+\S[^\v\f\r\n]*\r?\n){1,100}---[^\S\v\f\r\n]*(?:$|\r?\n)/y, (0, combinator_1.convert)(source => (0, normalize_1.normalize)(source.slice(source.indexOf('\n') + 1, source.trimEnd().lastIndexOf('\n'))).replace(/(\S)\s+$/mg, '$1'), (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.union)([field])), es => [(0, dom_1.html)('aside', {
5692
+ }) => context.header ?? true, (0, combinator_1.focus)(/(---+)[^\S\v\f\r\n]*\r?\n(?:[A-Za-z][0-9A-Za-z]*(?:-[A-Za-z][0-9A-Za-z]*)*:[ \t]+\S[^\v\f\r\n]*\r?\n){1,100}\1[^\S\v\f\r\n]*(?:$|\r?\n)/y, (0, combinator_1.convert)(source => (0, normalize_1.normalize)(source.slice(source.indexOf('\n') + 1, source.trimEnd().lastIndexOf('\n'))).replace(/(\S)\s+$/mg, '$1'), (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.union)([field])), es => [(0, dom_1.html)('aside', {
5683
5693
  class: 'header'
5684
5694
  }, [(0, dom_1.html)('details', {
5685
5695
  open: ''
@@ -6737,17 +6747,17 @@ const attrspecs = {
6737
6747
  };
6738
6748
  Object.setPrototypeOf(attrspecs, null);
6739
6749
  Object.values(attrspecs).forEach(o => Object.setPrototypeOf(o, null));
6740
- exports.html = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/<[a-z]+(?=[^\S\n]|>)/yi, (0, combinator_1.union)([(0, combinator_1.surround)(
6750
+ exports.html = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/<[a-z]+(?=[ >])/yi, (0, combinator_1.union)([(0, combinator_1.surround)(
6741
6751
  // https://html.spec.whatwg.org/multipage/syntax.html#void-elements
6742
- (0, source_1.str)(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[^\S\n]|>)/yi), (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), (0, combinator_1.open)((0, source_1.str)(/[^\S\n]*/y), (0, source_1.str)('>'), true), true, ([as, bs = [], cs], context) => [[elem(as[0].slice(1), false, (0, array_1.push)((0, array_1.unshift)(as, bs), cs), [], [], context)]], ([as, bs = []], context) => [[elem(as[0].slice(1), false, (0, array_1.unshift)(as, bs), [], [], context)]]), (0, combinator_1.match)(new RegExp(String.raw`<(${TAGS.join('|')})(?=[^\S\n]|>)`, 'y'), (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, combinator_1.open)((0, source_1.str)(/[^\S\n]*/y), (0, source_1.str)('>'), true), true, ([as, bs = [], cs]) => [(0, array_1.push)((0, array_1.unshift)(as, bs), cs)], ([as, bs = []]) => [(0, array_1.unshift)(as, bs)]),
6752
+ (0, source_1.str)(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[ >])/yi), (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), (0, combinator_1.open)((0, source_1.str)(/ ?/y), (0, source_1.str)('>'), true), true, ([as, bs = [], cs], context) => [[elem(as[0].slice(1), false, (0, array_1.push)((0, array_1.unshift)(as, bs), cs), [], [], context)]], ([as, bs = []], context) => [[elem(as[0].slice(1), false, (0, array_1.unshift)(as, bs), [], [], context)]]), (0, combinator_1.match)(new RegExp(String.raw`<(${TAGS.join('|')})(?=[^\S\n]|>)`, 'y'), (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, combinator_1.open)((0, source_1.str)(/ ?/y), (0, source_1.str)('>'), true), true, ([as, bs = [], cs]) => [(0, array_1.push)((0, array_1.unshift)(as, bs), cs)], ([as, bs = []]) => [(0, array_1.unshift)(as, bs)]),
6743
6753
  // 不可視のHTML構造が可視構造を変化させるべきでない。
6744
6754
  // 可視のHTMLは優先度変更を検討する。
6745
6755
  // このため<>は将来的に共通構造を変化させる可能性があり
6746
- // 共通構造を変更させない非構造文字列としては依然としてエスケープを要する。
6756
+ // 共通構造を変化させない非構造文字列としては依然としてエスケープを要する。
6747
6757
  (0, combinator_1.precedence)(0, (0, combinator_1.recursion)(4 /* Recursion.inline */, (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, visibility_1.blankWith)('\n', `</${tag}>`)), (0, combinator_1.open)('\n', (0, combinator_1.some)(inline_1.inline, `</${tag}>`), true)])))), (0, source_1.str)(`</${tag}>`), true, ([as, bs = [], cs], context) => [[elem(tag, true, as, bs, cs, context)]], ([as, bs = []], context) => [[elem(tag, true, as, bs, [], context)]]), ([, tag]) => tag, new Map())), (0, combinator_1.surround)(
6748
6758
  // https://html.spec.whatwg.org/multipage/syntax.html#void-elements
6749
- (0, source_1.str)(/<[a-z]+(?=[^\S\n]|>)/yi), (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), (0, combinator_1.open)((0, source_1.str)(/[^\S\n]*/y), (0, source_1.str)('>'), true), true, ([as, bs = [], cs], context) => [[elem(as[0].slice(1), false, (0, array_1.push)((0, array_1.unshift)(as, bs), cs), [], [], context)]], ([as, bs = []], context) => [[elem(as[0].slice(1), false, (0, array_1.unshift)(as, bs), [], [], context)]])])));
6750
- exports.attribute = (0, combinator_1.union)([(0, source_1.str)(/[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|>)/yi), (0, source_1.str)(/[^\S\n]+[^\s<>]+/y)]);
6759
+ (0, source_1.str)(/<[a-z]+(?=[ >])/yi), (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), (0, combinator_1.open)((0, source_1.str)(/ ?/y), (0, source_1.str)('>'), true), true, ([as, bs = [], cs], context) => [[elem(as[0].slice(1), false, (0, array_1.push)((0, array_1.unshift)(as, bs), cs), [], [], context)]], ([as, bs = []], context) => [[elem(as[0].slice(1), false, (0, array_1.unshift)(as, bs), [], [], context)]])])));
6760
+ exports.attribute = (0, combinator_1.union)([(0, source_1.str)(/ [a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[ >])/yi), (0, source_1.str)(/ [^\s<>]+/y)]);
6751
6761
  function elem(tag, content, as, bs, cs, context) {
6752
6762
  if (!tags.includes(tag)) return ielem('tag', `Invalid HTML tag name "${tag}"`, context);
6753
6763
  if (content) {
@@ -6916,7 +6926,7 @@ Object.setPrototypeOf(optspec, null);
6916
6926
  exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */, (0, combinator_1.creation)(10, (0, combinator_1.precedence)(1, (0, combinator_1.state)(251 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.subsequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[']', 1]])), ']', true, ([, ns = []], context) => context.linebreak === 0 ? [(0, array_1.push)(ns, ["\u001F" /* Command.Separator */])] : undefined, undefined, [3 | 64 /* Backtrack.bracket */, 3 | 16 /* Backtrack.link */, 2 | 8 /* Backtrack.ruby */])),
6917
6927
  // `{ `と`{`で個別にバックトラックが発生し+1nされる。
6918
6928
  // 自己再帰的にパースしてもオプションの不要なパースによる計算量の増加により相殺される。
6919
- (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /[^\S\n]*}/y, false, undefined, ([as, bs], context) => {
6929
+ (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), / ?}/y, false, undefined, ([as, bs], context) => {
6920
6930
  if (!bs) return;
6921
6931
  const head = context.position - context.range;
6922
6932
  (0, combinator_1.setBacktrack)(context, [2 | 16 /* Backtrack.link */], head);
@@ -6942,10 +6952,10 @@ exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /
6942
6952
  if (content.length !== 0 && (0, visibility_1.trimBlankNodeEnd)(content).length === 0) return;
6943
6953
  return [[parse((0, dom_1.defrag)(content), params, context)]];
6944
6954
  }))))));
6945
- exports.medialink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */ | 4 /* State.media */, (0, combinator_1.validate)(/[[{]/y, (0, combinator_1.creation)(10, (0, combinator_1.state)(251 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /[^\S\n]*}/y))])), ([params, content = []], context) => [[parse((0, dom_1.defrag)(content), params, context)]]))))));
6946
- exports.unsafelink = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(10, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([source_1.unescsource]), ']'), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /[^\S\n]*}/y))])), ([params, content = []], context) => [[parse((0, dom_1.defrag)(content), params, context)]])));
6947
- exports.uri = (0, combinator_1.union)([(0, combinator_1.open)(/[^\S\n]+/y, (0, source_1.str)(/\S+/y)), (0, source_1.str)(/[^\s{}]+/y)]);
6948
- exports.option = (0, combinator_1.union)([(0, combinator_1.fmap)((0, source_1.str)(/[^\S\n]+nofollow(?=[^\S\n]|})/y), () => [` rel="nofollow"`]), (0, source_1.str)(/[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|})/yi), (0, source_1.str)(/[^\S\n]+[^\s{}]+/y)]);
6955
+ exports.medialink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */ | 4 /* State.media */, (0, combinator_1.validate)(/[[{]/y, (0, combinator_1.creation)(10, (0, combinator_1.state)(251 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), / ?}/y))])), ([params, content = []], context) => [[parse((0, dom_1.defrag)(content), params, context)]]))))));
6956
+ exports.unsafelink = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(10, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([source_1.unescsource]), ']'), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), / ?}/y))])), ([params, content = []], context) => [[parse((0, dom_1.defrag)(content), params, context)]])));
6957
+ exports.uri = (0, combinator_1.union)([(0, combinator_1.open)(/ /y, (0, source_1.str)(/\S+/y)), (0, source_1.str)(/[^\s{}]+/y)]);
6958
+ exports.option = (0, combinator_1.union)([(0, combinator_1.fmap)((0, source_1.str)(/ nofollow(?=[ }])/y), () => [` rel="nofollow"`]), (0, source_1.str)(/ [a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[ }])/yi), (0, source_1.str)(/ [^\s{}]+/y)]);
6949
6959
  function parse(content, params, context) {
6950
6960
  const INSECURE_URI = params.shift();
6951
6961
  let uri;
@@ -6966,11 +6976,11 @@ function elem(INSECURE_URI, content, uri, origin) {
6966
6976
  case 'http:':
6967
6977
  case 'https:':
6968
6978
  switch (true) {
6969
- case /[a-z][0-9]*:\/{0,2}\S/i.test((0, util_1.stringify)(content)):
6979
+ case /[0-9a-z]:\S/i.test((0, util_1.stringify)(content)):
6970
6980
  type = 'content';
6971
6981
  message = 'URI must not be contained';
6972
6982
  break;
6973
- case INSECURE_URI.slice(0, 2) === '^/' && /\/\.\.?(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/))):
6983
+ case INSECURE_URI.startsWith('^/') && /\/\.\.?(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/))):
6974
6984
  type = 'argument';
6975
6985
  message = 'Dot-segments cannot be used in subresource paths';
6976
6986
  break;
@@ -7007,13 +7017,13 @@ function elem(INSECURE_URI, content, uri, origin) {
7007
7017
  }
7008
7018
  function resolve(uri, host, source) {
7009
7019
  switch (true) {
7010
- case uri.slice(0, 2) === '^/':
7020
+ case uri.startsWith('^/'):
7011
7021
  const last = host.pathname.slice(host.pathname.lastIndexOf('/') + 1);
7012
7022
  return last.includes('.') // isFile
7013
7023
  // Exclude ISO 6709.
7014
7024
  && /^[0-9]*[a-z][0-9a-z]*$/i.test(last.slice(last.lastIndexOf('.') + 1)) ? `${host.pathname.slice(0, -last.length)}${uri.slice(2)}` : `${host.pathname.replace(/\/?$/, '/')}${uri.slice(2)}`;
7015
7025
  case host.origin === source.origin && host.pathname === source.pathname:
7016
- case uri.slice(0, 2) === '//':
7026
+ case uri.startsWith('//'):
7017
7027
  return uri;
7018
7028
  default:
7019
7029
  const target = new url_1.ReadonlyURL(uri, source.href);
@@ -7022,13 +7032,11 @@ function resolve(uri, host, source) {
7022
7032
  }
7023
7033
  exports.resolve = resolve;
7024
7034
  function decode(uri) {
7025
- const origin = uri.match(/[a-z](?:[-.](?=[0-9a-z])|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/yi)?.[0] ?? '';
7035
+ const head = /^[a-z]+(?:[.+-][0-9a-z]+)*:\/*[^/?#\s]+/i;
7036
+ const origin = uri.match(head)?.[0] ?? '';
7026
7037
  try {
7027
- let path = decodeURI(uri.slice(origin.length));
7028
- if (!origin && /[a-z](?:[-.](?=[0-9a-z])|[0-9a-z])*:\/{0,2}\S/yi.test(path)) {
7029
- path = uri.slice(origin.length);
7030
- }
7031
- uri = origin + path;
7038
+ const path = decodeURI(uri.slice(origin.length));
7039
+ uri = !origin && head.test(path) ? uri.slice(origin.length) : origin + path;
7032
7040
  } finally {
7033
7041
  return uri.replace(/\s+/g, encodeURI);
7034
7042
  }
@@ -7134,7 +7142,7 @@ const optspec = {
7134
7142
  rel: undefined
7135
7143
  };
7136
7144
  Object.setPrototypeOf(optspec, null);
7137
- exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* State.media */, (0, combinator_1.creation)(10, (0, combinator_1.open)('!', (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']')), ']', true, ([, ns = []], context) => context.linebreak === 0 ? [ns] : undefined, undefined, [3 | 4 /* Backtrack.escbracket */])), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)]), /[^\S\n]*}/y, false, undefined, ([as, bs], context) => {
7145
+ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* State.media */, (0, combinator_1.creation)(10, (0, combinator_1.open)('!', (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']')), ']', true, ([, ns = []], context) => context.linebreak === 0 ? [ns] : undefined, undefined, [3 | 4 /* Backtrack.escbracket */])), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)]), / ?}/y, false, undefined, ([as, bs], context) => {
7138
7146
  if (!bs) return;
7139
7147
  const head = context.position - context.range;
7140
7148
  (0, combinator_1.setBacktrack)(context, [2 | 16 /* Backtrack.link */], head);
@@ -7183,7 +7191,7 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* S
7183
7191
  })((0, parser_1.subinput)(`{ ${INSECURE_URI}${linkparams.join('')} }`, context));
7184
7192
  })))));
7185
7193
  const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ')'), (0, source_1.str)(')'), true, undefined, () => [[]], [3 | 4 /* Backtrack.escbracket */]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']'), (0, source_1.str)(']'), true, undefined, () => [[]], [3 | 4 /* Backtrack.escbracket */]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), '}'), (0, source_1.str)('}'), true, undefined, () => [[]], [3 | 4 /* Backtrack.escbracket */]), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, source_1.txt]), '"')), (0, source_1.str)('"'), true, undefined, () => [[]], [3 | 4 /* Backtrack.escbracket */])])));
7186
- const option = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, combinator_1.open)(/[^\S\n]+/y, (0, source_1.str)(/[1-9][0-9]*/y)), (0, source_1.str)(/[x:]/y), (0, source_1.str)(/[1-9][0-9]*(?=[^\S\n]|})/y), false, ([[a], [b], [c]]) => [b === 'x' ? [`width="${a}"`, `height="${c}"`] : [`aspect-ratio="${a}/${c}"`]]), link_1.option]));
7194
+ const option = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, combinator_1.open)(/ /y, (0, source_1.str)(/[1-9][0-9]*/y)), (0, source_1.str)(/[x:]/y), (0, source_1.str)(/[1-9][0-9]*(?=[ }])/y), false, ([[a], [b], [c]]) => [b === 'x' ? [`width="${a}"`, `height="${c}"`] : [`aspect-ratio="${a}/${c}"`]]), link_1.option]));
7187
7195
  function sanitize(target, uri) {
7188
7196
  let type;
7189
7197
  let message;
@@ -7994,7 +8002,7 @@ exports.escsource = void 0;
7994
8002
  const combinator_1 = __webpack_require__(3484);
7995
8003
  const text_1 = __webpack_require__(5655);
7996
8004
  const dom_1 = __webpack_require__(394);
7997
- const delimiter = /(?=[\\$"`\[\](){}\r\n]|\s(?:\$)|:\/\/)/g;
8005
+ const delimiter = /(?=[\\$"`\[\](){}\r\n]|\s\$|:\/\/)/g;
7998
8006
  const escsource = ({
7999
8007
  context
8000
8008
  }) => {
@@ -8030,9 +8038,7 @@ const escsource = ({
8030
8038
  return [[(0, dom_1.html)('br')]];
8031
8039
  default:
8032
8040
  if (context.sequential) return [[char]];
8033
- text_1.nonWhitespace.lastIndex = position + 1;
8034
- const b = (0, text_1.isBlank)(source, position);
8035
- let i = b ? source[position + 1] === '\n' ? position + 1 : text_1.nonWhitespace.test(source) ? text_1.nonWhitespace.lastIndex - 1 : source.length : (0, text_1.next)(source, position, delimiter);
8041
+ let i = (0, text_1.next)(source, position, delimiter);
8036
8042
  i -= position;
8037
8043
  (0, combinator_1.consume)(i - 1, context);
8038
8044
  context.position += i - 1;
@@ -8145,11 +8151,11 @@ exports.strs = strs;
8145
8151
  Object.defineProperty(exports, "__esModule", ({
8146
8152
  value: true
8147
8153
  }));
8148
- exports.isWhitespace = exports.isBlank = exports.backToEmailHead = exports.backToUrlHead = exports.next = exports.linebreak = exports.txt = exports.text = exports.nonWhitespace = void 0;
8154
+ exports.backToEmailHead = exports.backToUrlHead = exports.backToWhitespace = exports.next = exports.canSkip = exports.linebreak = exports.txt = exports.text = exports.nonWhitespace = void 0;
8149
8155
  const combinator_1 = __webpack_require__(3484);
8150
8156
  const dom_1 = __webpack_require__(394);
8151
8157
  //const delimiter = /(?=[\\!@#$&"`\[\](){}<>()[]{}*%|\r\n]|([+~=])\1|\/{3}|\s(?:\\?(?:$|\s)|[$%])|:\/\/)/g;
8152
- exports.nonWhitespace = /[\S\r\n]/g;
8158
+ exports.nonWhitespace = /[^ \t ]/g;
8153
8159
  const text = input => {
8154
8160
  const {
8155
8161
  context
@@ -8184,22 +8190,39 @@ const text = input => {
8184
8190
  default:
8185
8191
  if (context.sequential) return [[char]];
8186
8192
  exports.nonWhitespace.lastIndex = position + 1;
8187
- const b = isBlank(source, position);
8188
- let i = b ? source[position + 1] === '\n' ? position + 1 : exports.nonWhitespace.test(source) ? exports.nonWhitespace.lastIndex - 1 : source.length : next(source, position);
8189
- const lineend = false || b && i === source.length || b && source[i] === '\n' || b && source[i] === '\\' && source[i + 1] === '\n';
8193
+ const s = canSkip(source, position);
8194
+ let i = s ? exports.nonWhitespace.test(source) ? exports.nonWhitespace.lastIndex - 1 : source.length : next(source, position);
8195
+ const lineend = false || s && i === source.length || s && source[i] === '\n';
8190
8196
  i -= position;
8191
- i = lineend ? i : i - +b || 1;
8197
+ i = lineend ? i : i - +s || 1;
8192
8198
  (0, combinator_1.consume)(i - 1, context);
8193
8199
  context.position += i - 1;
8194
8200
  const linestart = position === 0 || source[position - 1] === '\n';
8195
- i = linestart && b && i >= 3 ? i - 3 : 0;
8196
- i += position;
8197
- return i === context.position || b && !linestart || lineend ? [[]] : [[source.slice(i, context.position)]];
8201
+ return position === context.position || s && !linestart || lineend ? [[]] : [[source.slice(position, context.position)]];
8198
8202
  }
8199
8203
  };
8200
8204
  exports.text = text;
8201
8205
  exports.txt = (0, combinator_1.union)([exports.text]);
8202
8206
  exports.linebreak = (0, combinator_1.focus)(/[\r\n]/y, (0, combinator_1.union)([exports.text]));
8207
+ function canSkip(source, position) {
8208
+ if (!isWhitespace(source[position], false)) return false;
8209
+ if (position + 1 === source.length) return true;
8210
+ return isWhitespace(source[position + 1], true);
8211
+ }
8212
+ exports.canSkip = canSkip;
8213
+ function isWhitespace(char, linebreak) {
8214
+ switch (char) {
8215
+ case ' ':
8216
+ case '\t':
8217
+ case ' ':
8218
+ return true;
8219
+ case '\r':
8220
+ case '\n':
8221
+ return linebreak;
8222
+ default:
8223
+ return false;
8224
+ }
8225
+ }
8203
8226
  function next(source, position, delimiter) {
8204
8227
  let index;
8205
8228
  if (delimiter) {
@@ -8212,8 +8235,20 @@ function next(source, position, delimiter) {
8212
8235
  if (index === 0) return source.length;
8213
8236
  const char = source[index];
8214
8237
  switch (char) {
8238
+ case '$':
8239
+ case '%':
8240
+ case '*':
8241
+ case '+':
8242
+ case '~':
8243
+ case '=':
8244
+ case '/':
8245
+ index = backToWhitespace(source, position, index);
8246
+ break;
8247
+ case '[':
8248
+ index = source[index + 1] === '|' ? backToWhitespace(source, position, index) : index;
8249
+ break;
8215
8250
  case ':':
8216
- index = backToUrlHead(source, position, index);
8251
+ index = source.startsWith('//', index + 1) ? backToUrlHead(source, position, index) : index;
8217
8252
  break;
8218
8253
  case '@':
8219
8254
  index = backToEmailHead(source, position, index);
@@ -8222,40 +8257,37 @@ function next(source, position, delimiter) {
8222
8257
  return index;
8223
8258
  }
8224
8259
  exports.next = next;
8260
+ function backToWhitespace(source, position, index) {
8261
+ const prev = index - 1;
8262
+ return prev > position && /\s/.test(source[prev]) ? prev : index;
8263
+ }
8264
+ exports.backToWhitespace = backToWhitespace;
8225
8265
  function backToUrlHead(source, position, index) {
8226
8266
  const delim = index;
8227
8267
  let state = false;
8228
- let offset = 0;
8229
- for (let i = index; --i > position;) {
8230
- index = i;
8268
+ for (let i = index - 1; i >= position; --i) {
8231
8269
  const char = source[i];
8232
8270
  if (state) switch (char) {
8233
8271
  case '.':
8234
8272
  case '+':
8235
8273
  case '-':
8236
8274
  state = false;
8237
- offset = 1;
8238
8275
  continue;
8239
8276
  }
8240
8277
  if (isAlphanumeric(char)) {
8241
8278
  state = true;
8242
- offset = 0;
8279
+ index = i;
8243
8280
  continue;
8244
8281
  }
8245
8282
  break;
8246
8283
  }
8247
- if (index === position + 1 && offset === 0 && isAlphanumeric(source[index - 1])) {
8248
- return delim;
8249
- }
8250
- return index + offset;
8284
+ return index === position ? delim : index;
8251
8285
  }
8252
8286
  exports.backToUrlHead = backToUrlHead;
8253
8287
  function backToEmailHead(source, position, index) {
8254
8288
  const delim = index;
8255
8289
  let state = false;
8256
- let offset = 0;
8257
- for (let i = index; --i > position;) {
8258
- index = i;
8290
+ for (let i = index - 1; i >= position; --i) {
8259
8291
  const char = source[i];
8260
8292
  if (state) switch (char) {
8261
8293
  case '_':
@@ -8263,20 +8295,16 @@ function backToEmailHead(source, position, index) {
8263
8295
  case '+':
8264
8296
  case '-':
8265
8297
  state = false;
8266
- offset = 1;
8267
8298
  continue;
8268
8299
  }
8269
8300
  if (isAlphanumeric(char)) {
8270
8301
  state = true;
8271
- offset = 0;
8302
+ index = i;
8272
8303
  continue;
8273
8304
  }
8274
8305
  break;
8275
8306
  }
8276
- if (index === position + 1 && offset === 0 && isAlphanumeric(source[index - 1])) {
8277
- return delim;
8278
- }
8279
- return index + offset;
8307
+ return index === position ? delim : index;
8280
8308
  }
8281
8309
  exports.backToEmailHead = backToEmailHead;
8282
8310
  function isAlphanumeric(char) {
@@ -8317,7 +8345,6 @@ function isAlphanumeric(char) {
8317
8345
  // this[c.charCodeAt(0)] = undefined);
8318
8346
  // }
8319
8347
  //};
8320
- const delimiter = /\s(?:\\?(?:$|\s)|[$%])/y;
8321
8348
  function seek(source, position) {
8322
8349
  for (let i = position + 1; i < source.length; ++i) {
8323
8350
  const fst = source[i];
@@ -8346,7 +8373,6 @@ function seek(source, position) {
8346
8373
  case '{':
8347
8374
  case '}':
8348
8375
  case '*':
8349
- case '%':
8350
8376
  case '|':
8351
8377
  case '\r':
8352
8378
  case '\n':
@@ -8359,77 +8385,41 @@ function seek(source, position) {
8359
8385
  case '/':
8360
8386
  if (source[i + 1] === fst && source[i + 2] === fst) return i;
8361
8387
  continue;
8388
+ case '%':
8389
+ if (source[i + 1] === ']') return i;
8390
+ continue;
8362
8391
  case ':':
8363
8392
  if (source[i + 1] === '/' && source[i + 2] === '/') return i;
8364
8393
  continue;
8365
- //case ' ':
8366
- //case '\t':
8367
- //case ' ':
8368
- // if (i + 1 === source.length) return i;
8369
- // switch (source[i + 1]) {
8370
- // case ' ':
8371
- // case '\t':
8372
- // case '\r':
8373
- // case '\n':
8374
- // case ' ':
8375
- // case '$':
8376
- // case '%':
8377
- // return i;
8378
- // case '\\':
8379
- // if (i + 2 === source.length) return i;
8380
- // switch (source[i + 2]) {
8381
- // case ' ':
8382
- // case '\t':
8383
- // case '\r':
8384
- // case '\n':
8385
- // case ' ':
8386
- // return i;
8387
- // }
8388
- // }
8389
- // continue;
8394
+ case ' ':
8395
+ case '\t':
8396
+ case ' ':
8397
+ if (i + 1 === source.length) return i;
8398
+ switch (source[i + 1]) {
8399
+ case ' ':
8400
+ case '\t':
8401
+ case '\r':
8402
+ case '\n':
8403
+ case ' ':
8404
+ return i;
8405
+ case '\\':
8406
+ if (i + 2 === source.length) return i;
8407
+ switch (source[i + 2]) {
8408
+ case ' ':
8409
+ case '\t':
8410
+ case '\r':
8411
+ case '\n':
8412
+ case ' ':
8413
+ return i;
8414
+ }
8415
+ }
8416
+ continue;
8390
8417
  default:
8391
- delimiter.lastIndex = i;
8392
- if (delimiter.test(source)) return i;
8393
8418
  continue;
8394
8419
  }
8395
8420
  }
8396
8421
  return source.length;
8397
8422
  }
8398
- const blank = /\s(?:$|\s|\\\n)/y;
8399
- function isBlank(source, position) {
8400
- blank.lastIndex = position;
8401
- return blank.test(source);
8402
- // removed by dead control flow
8403
-
8404
- // removed by dead control flow
8405
-
8406
- // removed by dead control flow
8407
-
8408
- // removed by dead control flow
8409
-
8410
- // removed by dead control flow
8411
-
8412
- // removed by dead control flow
8413
-
8414
- // removed by dead control flow
8415
-
8416
- }
8417
- exports.isBlank = isBlank;
8418
- const whitespace = /\s/;
8419
- function isWhitespace(char) {
8420
- whitespace;
8421
- switch (char) {
8422
- case ' ':
8423
- case '\t':
8424
- case '\r':
8425
- case '\n':
8426
- case ' ':
8427
- return true;
8428
- default:
8429
- return false;
8430
- }
8431
- }
8432
- exports.isWhitespace = isWhitespace;
8433
8423
 
8434
8424
  /***/ },
8435
8425
 
@@ -8472,8 +8462,7 @@ const unescsource = ({
8472
8462
  default:
8473
8463
  if (context.sequential) return [[char]];
8474
8464
  text_1.nonWhitespace.lastIndex = position + 1;
8475
- const b = (0, text_1.isBlank)(source, position);
8476
- let i = b ? source[position + 1] === '\n' ? position + 1 : text_1.nonWhitespace.test(source) ? text_1.nonWhitespace.lastIndex - 1 : source.length : (0, text_1.next)(source, position, exports.delimiter);
8465
+ let i = (0, text_1.canSkip)(source, position) ? text_1.nonWhitespace.test(source) ? text_1.nonWhitespace.lastIndex - 1 : source.length : (0, text_1.next)(source, position, exports.delimiter);
8477
8466
  i -= position;
8478
8467
  (0, combinator_1.consume)(i - 1, context);
8479
8468
  context.position += i - 1;
@@ -8493,15 +8482,10 @@ exports.unescsource = unescsource;
8493
8482
  Object.defineProperty(exports, "__esModule", ({
8494
8483
  value: true
8495
8484
  }));
8496
- exports.stringify = exports.unmarkInvalid = exports.markInvalid = exports.invalid = exports.repeat = exports.linearize = void 0;
8485
+ exports.stringify = exports.unmarkInvalid = exports.markInvalid = exports.invalid = exports.repeat = void 0;
8497
8486
  const alias_1 = __webpack_require__(5413);
8498
8487
  const parser_1 = __webpack_require__(605);
8499
- const combinator_1 = __webpack_require__(3484);
8500
8488
  const dom_1 = __webpack_require__(394);
8501
- function linearize(parser, trim = 0) {
8502
- return (0, combinator_1.convert)(source => `${trim === 0 ? source : trim > 0 ? source.at(-1) === '\n' ? source : source + '\n' : source.at(-1) === '\n' ? source.slice(0, -1) : source}`, parser, trim === 0);
8503
- }
8504
- exports.linearize = linearize;
8505
8489
  function repeat(symbol, parser, cons, termination = (nodes, context, prefix, postfix) => {
8506
8490
  const acc = [];
8507
8491
  if (prefix > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.293.3",
3
+ "version": "0.293.5",
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",
@@ -157,8 +157,8 @@ export function setBacktrack(
157
157
  position: number,
158
158
  length: number = 1,
159
159
  ): void {
160
- const { source, state = 0 } = context;
161
- if (state === 0) return;
160
+ // 以降バックトラックの可能性がなく記録不要の場合もあるが判別が面倒なので省略
161
+ const { source } = context;
162
162
  if (position === source.length) return;
163
163
  if (length === 0) return;
164
164
  for (const backtrack of backtracks) {
@@ -22,16 +22,16 @@ describe('Unit: combinator/data/parser/context', () => {
22
22
  assert(base.resources?.clock === 3);
23
23
  assert(ctx.resources?.clock === undefined);
24
24
  assert.throws(() => reset(base, parser)(input('1234', ctx)));
25
- assert(ctx.resources?.clock === 0);
25
+ assert(ctx.resources?.clock === undefined);
26
26
  });
27
27
 
28
28
  it('node', () => {
29
29
  const base: Context = { resources: { clock: 3, recursions: [1] } };
30
- const ctx: Context = { resources: { clock: 1, recursions: [1] } };
31
- assert.deepStrictEqual(reset(base, parser)(input('1', ctx)), [[1]]);
30
+ const ctx: Context = { resources: { clock: 2, recursions: [1] } };
31
+ assert.deepStrictEqual(reset(base, parser)(input('1', ctx)), [[2]]);
32
32
  assert(base.resources?.clock === 3);
33
- assert(ctx.resources?.clock === 0);
34
- assert.throws(() => reset(base, parser)(input('1', ctx)));
33
+ assert(ctx.resources?.clock === 1);
34
+ assert.throws(() => reset(base, parser)(input('12', ctx)));
35
35
  assert(ctx.resources?.clock === 0);
36
36
  });
37
37
 
@@ -46,11 +46,12 @@ describe('Unit: combinator/data/parser/context', () => {
46
46
 
47
47
  it('', () => {
48
48
  const base: Context = { status: true };
49
- const ctx: Context = { resources: { clock: 3, recursions: [1] } };
50
- assert.deepStrictEqual(context(base, parser)(input('123', ctx)), [[true, true, true]]);
51
- assert(ctx.resources?.clock === 0);
49
+ const ctx: Context = { resources: { clock: 2, recursions: [1] } };
50
+ assert.deepStrictEqual(context(base, parser)(input('1', ctx)), [[true]]);
51
+ assert(base.resources?.clock === undefined);
52
+ assert(ctx.resources?.clock === 1);
52
53
  assert(ctx.status === undefined);
53
- assert.throws(() => reset(base, parser)(input('1', ctx)));
54
+ assert.throws(() => context(base, parser)(input('12', ctx)));
54
55
  assert(ctx.resources?.clock === 0);
55
56
  assert(ctx.status === true);
56
57
  });
@@ -9,7 +9,8 @@ export function reset<N>(base: Ctx, parser: Parser<N>): Parser<N> {
9
9
  const changes = Object.entries(base);
10
10
  const values = Array(changes.length);
11
11
  return ({ context }) =>
12
- apply(parser, context, changes, values, true);
12
+ // 大域離脱時の汚染回避のため複製
13
+ apply(parser, { ...context }, changes, values, true);
13
14
  }
14
15
 
15
16
  export function context<P extends Parser<unknown>>(base: CtxOptions, parser: P): P;