securemark 0.280.7 → 0.280.8

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,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.280.8
4
+
5
+ - Fix dependencies.
6
+
3
7
  ## 0.280.7
4
8
 
5
9
  - Refactoring.
package/design.md CHANGED
@@ -285,7 +285,7 @@ CodeMirrorが素では速いがVimModeでは数万文字程度でも耐え難く
285
285
 
286
286
  ### バックトラック
287
287
 
288
- SecuremarkのAnnotation構文に典型的であるように文脈を変更する構文の中にその文脈に依存し変更される他の構文が存在する場合一般に文脈の相違から解析結果を再利用不能な(`αA'β | αAB`)バックトラックが生じる。文脈依存構文の解析中に文脈により解釈の異なる字句(`[a((`)または現在の文脈を終了する字句(ただの括弧がスコープを作らない場合の`(([a))`)に遭遇したとき、現在の文脈での解析の継続を試行する解析方法はメモ化なしではバックトラックが再帰的に生じ線形時間で解析できず、現在の文脈での解析を中止し直前の文脈を継続または新たな文脈を開始する解析方法はバックトラックなしで線形時間で解析できる。
288
+ SecuremarkのAnnotation構文に典型的であるように文脈を変更する構文の中にその文脈に依存し変更される他の構文が存在する場合一般に文脈の相違から解析結果を再利用不能な(`αA'β | αAB`)バックトラックが生じる。文脈依存構文の解析中に文脈により解釈の異なる字句(`[a((`)または現在の文脈を終了する字句(ただの括弧がスコープを作らない場合の`(([a))`)に遭遇したとき、現在の文脈での解析の継続を試行する解析方法はメモ化なしではバックトラックが再帰的に生じ線形時間で解析できず、現在の文脈での解析を中止し直前の文脈を継続または新たな文脈を開始する解析方法はバックトラックなしで線形時間で解析できる(バッファまたは解析試行ログを使用して解釈を変更する実装方法があるが開始記号の一部が重複しないよう構文が制限される場合がある)。
289
289
  CommonMarkはLink構文から明らかなように後者の解析方法により再帰的バックトラックなし(Markdown(2n)+正規表現(1n)で最悪計算量3n程度)で解析できる言語であるが同時にこれは文脈依存構文の正当な入れ子表現を解析できず文脈依存構文の存在する数に応じて多項式的(おそらく$n^{2+c}$)に構文の壊れやすさの増す脆く拡張性の低い言語であることを意味する。この問題はおそらくメモ化により解決できるがCommonMarkは実行性能追及のためメモ化を廃止しているためメモ化により性能を低下させてまで解決するつもりはないと思われる(すなわちCommonMarkは機械を至上とし人間に制約を課す低水準の言語であり人間の需要を至上とするSecuremarkとは対極に位置する)。
290
290
  従って現在の再帰的バックトラックなしで解析可能な文法に制約されるCommonMarkには文脈依存構文を入れ子表現の広範な制限ならびに構文の可読性および開始記号の信頼性の多項式的な低下と引き換えにしか追加できないという拡張性の欠陥が存在する。CommonMarkの仕様策定者が構文の拡張に(名称を維持するか否かにかかわらず)不自然なまでに消極的または進展がないのは正当な理由や怠慢からでなく文脈依存構文を追加するにつれて構文解析戦略の欠陥が明白になっていくためおよび現在の高い実行性能を低下させたくないためである。`~~a~~`のような文脈自由構文は容易に追加できるがこうしたマージンを失えばもはや後はない。CommonMarkは小さく単純であるがゆえに正しくいられる象牙の塔であり仕様策定者はこの正しさを失わず正しいままでいたいがために象牙の塔に引きこもり小さな完全性を固持し続けているのである(でなければ何年も隠さず速やかにこの拡張性の欠如を公表して助力を求めていなければならない)。
291
291
  Securemarkは線形時間で解析不能な前者の解析方法をメモ化によりおおよそ4n以下の最悪計算量に改善しさらに解析時間と解析範囲の局限により一定時間内で解析不能な入力の影響を局限することでこれらの問題を解決している。この解析方法はほとんどの自然な入力に対して1nに近い時間で効率的に動作し、最悪計算量で低速に動作させる少数の機械的攻撃入力に対してもサーバーで多数のユーザーのリクエストに応じるには低速で脆弱性となる可能性があるがクライアントで単一のユーザーの操作に応じるには十分高速であるためクライアントで解析する限り解析の効率または速度が実用上問題となることはない。
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.280.7 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.280.8 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"));
@@ -395,13 +395,13 @@ DWCはこの最適化を行っても状態数の多さに比例して増加し
395
395
 
396
396
  */
397
397
  class Entry {
398
- constructor(key, value, size, partition, affiliation, expiration) {
398
+ constructor(key, value, size, expiration, partition, affiliation) {
399
399
  this.key = key;
400
400
  this.value = value;
401
401
  this.size = size;
402
+ this.expiration = expiration;
402
403
  this.partition = partition;
403
404
  this.affiliation = affiliation;
404
- this.expiration = expiration;
405
405
  this.enode = undefined;
406
406
  this.next = undefined;
407
407
  this.prev = undefined;
@@ -631,7 +631,7 @@ class Cache {
631
631
  if (entry.partition === 'LRU') {
632
632
  if (entry.affiliation === 'LRU') {
633
633
  // For memoize.
634
- // Strict checks are ineffective for OLTP.
634
+ // Strict checks are ineffective with OLTP.
635
635
  if (entry === LRU.head) return;
636
636
  entry.affiliation = 'LFU';
637
637
  } else {
@@ -690,7 +690,7 @@ class Cache {
690
690
  return true;
691
691
  }
692
692
  this.$size += size;
693
- const entry = new Entry(key, value, size, 'LRU', 'LRU', expiration);
693
+ const entry = new Entry(key, value, size, expiration, 'LRU', 'LRU');
694
694
  LRU.unshift(entry);
695
695
  this.dict.set(key, entry);
696
696
  if (this.expiration && this.expirations !== undefined && expiration !== Infinity) {
@@ -768,7 +768,6 @@ class Cache {
768
768
  } of this.LFU) {
769
769
  yield [key, value];
770
770
  }
771
- return;
772
771
  }
773
772
  }
774
773
  exports.Cache = Cache;
@@ -843,7 +842,6 @@ class Sweeper {
843
842
  }
844
843
  isActive() {
845
844
  if (this.threshold === 0) return false;
846
- if (this.prevWindowHits === 0 && this.prevWindowMisses === 0) return false;
847
845
  return this.active ??= this.ratioWindow() < (0, alias_1.max)(this.ratioRoom() * this.ratio / 100, this.threshold);
848
846
  }
849
847
  ratioWindow() {
@@ -907,6 +905,7 @@ function ratio(window, targets, remains, offset) {
907
905
  const currRatio = currTotal * 100 / window - offset;
908
906
  if (currRatio <= 0) return prevRate * 100 | 0;
909
907
  const currRate = currHits && currHits * 100 / currTotal;
908
+ if (prevTotal === 0) return currRate * 100 | 0;
910
909
  const prevRatio = 100 - currRatio;
911
910
  return currRate * currRatio + prevRate * prevRatio | 0;
912
911
  }
@@ -1051,21 +1050,27 @@ class Clock {
1051
1050
  capacity,
1052
1051
  refs
1053
1052
  } = this;
1054
- let hand = this.hand;
1055
- for (let i = hand >>> DIGIT, r = hand & MASK, len = refs.length;;) {
1053
+ for (let {
1054
+ hand
1055
+ } = this, i = hand >>> DIGIT, r = hand & MASK;;) {
1056
1056
  const b = refs[i];
1057
1057
  if (b >>> r === ~0 >>> r) {
1058
- hand += BASE - r;
1058
+ hand = hand + BASE - r;
1059
1059
  refs[i] = 0;
1060
1060
  r = 0;
1061
- if (++i === len) {
1061
+ if (hand < capacity) {
1062
+ ++i;
1063
+ } else {
1064
+ hand -= capacity;
1062
1065
  i = 0;
1063
1066
  }
1064
1067
  continue;
1065
1068
  }
1066
1069
  const l = search(b, r);
1067
- refs[i] = b & ~((1 << l) - 1 >>> r << r);
1068
- hand = (hand + l - r) % capacity;
1070
+ if (l !== r) {
1071
+ refs[i] = b & ~((1 << l) - 1 >>> r << r);
1072
+ hand += l - r;
1073
+ }
1069
1074
  this.locate(hand, key, value);
1070
1075
  return hand;
1071
1076
  }
@@ -1107,10 +1112,12 @@ class Clock {
1107
1112
  const v = values[index] = values[hand];
1108
1113
  keys[hand] = undefined;
1109
1114
  values[hand] = empty;
1110
- this.unmark(index);
1111
- if (index === hand || v === empty) return true;
1115
+ if (index === hand || v === empty) {
1116
+ this.unmark(index);
1117
+ return true;
1118
+ }
1112
1119
  dict.set(k, index);
1113
- refs[index >>> DIGIT] |= (refs[hand >>> DIGIT] & 1 << (hand & MASK)) === 0 ? 0 : 1 << (index & MASK);
1120
+ (refs[hand >>> DIGIT] & 1 << (hand & MASK)) === 0 ? this.unmark(index) : this.mark(index);
1114
1121
  this.unmark(hand);
1115
1122
  return true;
1116
1123
  }
@@ -1118,9 +1125,10 @@ class Clock {
1118
1125
  this.dict = new Map();
1119
1126
  this.keys = [];
1120
1127
  this.values = [];
1121
- this.refs = new Uint32Array(this.refs.length);
1128
+ this.refs.fill(0);
1122
1129
  this.hand = 0;
1123
1130
  this.$length = 0;
1131
+ this.initial = 1;
1124
1132
  }
1125
1133
  *[Symbol.iterator]() {
1126
1134
  const {
@@ -1130,7 +1138,6 @@ class Clock {
1130
1138
  for (const index of this.dict.values()) {
1131
1139
  yield [keys[index], values[index]];
1132
1140
  }
1133
- return;
1134
1141
  }
1135
1142
  }
1136
1143
  exports.Clock = Clock;
@@ -1832,17 +1839,38 @@ Object.defineProperty(exports, "__esModule", ({
1832
1839
  exports.reduce = exports.memoize = void 0;
1833
1840
  const alias_1 = __webpack_require__(5406);
1834
1841
  const compare_1 = __webpack_require__(5529);
1835
- function memoize(f, identify = (...as) => as[0], memory) {
1836
- if (typeof identify === 'object') return memoize(f, undefined, identify);
1837
- return (0, alias_1.isArray)(memory) || memory?.constructor === Object ? memoizeRecord(f, identify, memory) : memoizeDict(f, identify, memory ?? new Map());
1842
+ function memoize(f, identify, memory) {
1843
+ if (typeof identify === 'object') {
1844
+ memory = identify;
1845
+ identify = undefined;
1846
+ }
1847
+ identify ??= (...as) => as[0];
1848
+ switch (true) {
1849
+ case (0, alias_1.isArray)(memory):
1850
+ return memoizeArray(f, identify, memory);
1851
+ case memory?.constructor === Object:
1852
+ return memoizeObject(f, identify, memory);
1853
+ default:
1854
+ return memoizeDict(f, identify, memory ?? new Map());
1855
+ }
1838
1856
  }
1839
1857
  exports.memoize = memoize;
1840
- function memoizeRecord(f, identify, memory) {
1858
+ function memoizeArray(f, identify, memory) {
1859
+ return (...as) => {
1860
+ const b = identify(...as);
1861
+ let z = memory[b];
1862
+ if (z !== undefined) return z;
1863
+ z = f(...as);
1864
+ memory[b] = z;
1865
+ return z;
1866
+ };
1867
+ }
1868
+ function memoizeObject(f, identify, memory) {
1841
1869
  let nullable = false;
1842
1870
  return (...as) => {
1843
1871
  const b = identify(...as);
1844
1872
  let z = memory[b];
1845
- if (z !== undefined || nullable && memory[b] !== undefined) return z;
1873
+ if (z !== undefined || nullable && b in memory) return z;
1846
1874
  z = f(...as);
1847
1875
  nullable ||= z === undefined;
1848
1876
  memory[b] = z;
@@ -1943,7 +1971,6 @@ class Queue {
1943
1971
  while (!this.isEmpty()) {
1944
1972
  yield this.pop();
1945
1973
  }
1946
- return;
1947
1974
  }
1948
1975
  }
1949
1976
  exports.Queue = Queue;
@@ -2026,7 +2053,6 @@ class PriorityQueue {
2026
2053
  while (!this.isEmpty()) {
2027
2054
  yield this.pop();
2028
2055
  }
2029
- return;
2030
2056
  }
2031
2057
  }
2032
2058
  exports.PriorityQueue = PriorityQueue;
@@ -2106,7 +2132,6 @@ class MultiQueue {
2106
2132
  yield [k, vs.pop()];
2107
2133
  }
2108
2134
  }
2109
- return;
2110
2135
  }
2111
2136
  }
2112
2137
  exports.MultiQueue = MultiQueue;
@@ -2122,7 +2147,7 @@ exports.MultiQueue = MultiQueue;
2122
2147
  Object.defineProperty(exports, "__esModule", ({
2123
2148
  value: true
2124
2149
  }));
2125
- exports.pcg32 = exports.xorshift = exports.unique = exports.rndAf = exports.rndAP = exports.rnd0_ = exports.rnd0Z = exports.rnd0v = exports.rnd0f = exports.rnd64 = exports.rnd62 = exports.rnd32 = exports.rnd16 = void 0;
2150
+ exports.pcg32 = exports.xorshift = exports.unique = exports.rndAf = exports.rndAP = exports.rnd0_ = exports.rnd0Z = exports.rnd0z = exports.rnd0v = exports.rnd0f = exports.rnd64 = exports.rnd62 = exports.rnd36 = exports.rnd32 = exports.rnd16 = void 0;
2126
2151
  const bases = Object.freeze([...Array(7)].map((_, i) => 1 << i));
2127
2152
  const masks = Object.freeze(bases.map(radix => radix - 1));
2128
2153
  const dict0_ = [...[...Array(36)].map((_, i) => i.toString(36)), ...[...Array(36)].map((_, i) => i.toString(36).toUpperCase()).slice(-26), '-', '_'].join('');
@@ -2135,10 +2160,12 @@ const dictAz = [...[...Array(36)].map((_, i) => i.toString(36).toUpperCase()).sl
2135
2160
 
2136
2161
  exports.rnd16 = cons(16);
2137
2162
  exports.rnd32 = cons(32);
2163
+ exports.rnd36 = cons(36);
2138
2164
  exports.rnd62 = cons(62);
2139
2165
  exports.rnd64 = cons(64);
2140
2166
  exports.rnd0f = conv(exports.rnd16, dict0_);
2141
2167
  exports.rnd0v = conv(exports.rnd32, dict0_);
2168
+ exports.rnd0z = conv(exports.rnd36, dict0_);
2142
2169
  exports.rnd0Z = conv(exports.rnd62, dict0_);
2143
2170
  exports.rnd0_ = conv(exports.rnd64, dict0_);
2144
2171
  exports.rndAP = conv(exports.rnd16, dictAz);
@@ -2219,14 +2246,14 @@ function xorshift(seed = xorshift.seed()) {
2219
2246
  return () => {
2220
2247
  let x = seed;
2221
2248
  x ^= x << 13;
2222
- x ^= x >> 17;
2249
+ x ^= x >>> 17;
2223
2250
  x ^= x << 15;
2224
2251
  return seed = x >>> 0;
2225
2252
  };
2226
2253
  }
2227
2254
  exports.xorshift = xorshift;
2228
2255
  (function (xorshift) {
2229
- const max = -1 >>> 0;
2256
+ const max = ~0 >>> 0;
2230
2257
  function seed() {
2231
2258
  return Math.random() * max + 1 >>> 0;
2232
2259
  }
@@ -2334,7 +2361,6 @@ class Stack {
2334
2361
  while (!this.isEmpty()) {
2335
2362
  yield this.pop();
2336
2363
  }
2337
- return;
2338
2364
  }
2339
2365
  }
2340
2366
  exports.Stack = Stack;
@@ -2413,26 +2439,29 @@ Object.defineProperty(exports, "__esModule", ({
2413
2439
  value: true
2414
2440
  }));
2415
2441
  exports.URL = exports.ReadonlyURL = exports.standardize = void 0;
2416
- const format_1 = __webpack_require__(137);
2417
- var format_2 = __webpack_require__(137);
2442
+ const internal_1 = __webpack_require__(2560);
2443
+ var internal_2 = __webpack_require__(2560);
2418
2444
  Object.defineProperty(exports, "standardize", ({
2419
2445
  enumerable: true,
2420
2446
  get: function () {
2421
- return format_2.standardize;
2447
+ return internal_2.standardize;
2422
2448
  }
2423
2449
  }));
2424
- var format_3 = __webpack_require__(137);
2450
+ var internal_3 = __webpack_require__(2560);
2425
2451
  Object.defineProperty(exports, "ReadonlyURL", ({
2426
2452
  enumerable: true,
2427
2453
  get: function () {
2428
- return format_3.ReadonlyURL;
2454
+ return internal_3.ReadonlyURL;
2429
2455
  }
2430
2456
  }));
2431
2457
  class URL {
2432
2458
  constructor(source, base) {
2459
+ source = source.trim();
2460
+ base = base?.trim();
2461
+ this.url = new internal_1.ReadonlyURL(source, base);
2462
+ this.params = undefined;
2433
2463
  this.source = source;
2434
2464
  this.base = base;
2435
- this.url = new format_1.ReadonlyURL(source, base);
2436
2465
 
2437
2466
  //assert(this.href.startsWith(this.resource));
2438
2467
  }
@@ -2447,7 +2476,7 @@ class URL {
2447
2476
  return this.url.origin;
2448
2477
  }
2449
2478
  get scheme() {
2450
- return this.url.protocol.slice(0, -1);
2479
+ return this.url.scheme;
2451
2480
  }
2452
2481
  get protocol() {
2453
2482
  return this.url.protocol;
@@ -2489,17 +2518,17 @@ class URL {
2489
2518
  return this.params ??= new URLSearchParams(this.search);
2490
2519
  }
2491
2520
  toString() {
2492
- return this.href;
2521
+ return this.url.toString();
2493
2522
  }
2494
2523
  toJSON() {
2495
- return this.href;
2524
+ return this.url.toJSON();
2496
2525
  }
2497
2526
  }
2498
2527
  exports.URL = URL;
2499
2528
 
2500
2529
  /***/ }),
2501
2530
 
2502
- /***/ 137:
2531
+ /***/ 2560:
2503
2532
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
2504
2533
 
2505
2534
  "use strict";
@@ -2508,28 +2537,37 @@ exports.URL = URL;
2508
2537
  Object.defineProperty(exports, "__esModule", ({
2509
2538
  value: true
2510
2539
  }));
2511
- exports.ReadonlyURL = exports._encode = exports.standardize = void 0;
2540
+ exports.ReadonlyURL = exports.encode = exports.standardize = void 0;
2512
2541
  __webpack_require__(4128);
2513
2542
  const memoize_1 = __webpack_require__(1808);
2514
2543
  const cache_1 = __webpack_require__(9210);
2515
2544
  function standardize(url, base) {
2516
- const u = new ReadonlyURL(url, base);
2517
- url = u.origin === 'null' ? u.protocol.toLowerCase() + u.href.slice(u.protocol.length) : u.origin.toLowerCase() + u.href.slice(u.origin.length);
2545
+ const {
2546
+ origin,
2547
+ protocol,
2548
+ href
2549
+ } = new ReadonlyURL(url, base);
2550
+ url = origin === 'null' ? protocol.toLowerCase() + href.slice(protocol.length) : origin.toLowerCase() + href.slice(origin.length);
2518
2551
  return encode(url);
2519
2552
  }
2520
2553
  exports.standardize = standardize;
2521
2554
  function encode(url) {
2522
- return url
2523
- // Percent-encoding
2524
- .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]?|[\uDC00-\uDFFF]/g, str => str.length === 2 ? str : '').replace(/%(?![0-9A-F]{2})|[^%\[\]]+/ig, encodeURI).replace(/\?[^#]+/, query => '?' + query.slice(1).replace(/%[0-9A-F]{2}|%|[^=&]+/ig, str => str[0] === '%' && str.length === 3 ? str : encodeURIComponent(str)))
2525
- // Use uppercase letters within percent-encoding triplets
2526
- .replace(/%[0-9A-F]{2}/ig, str => str.toUpperCase()).replace(/#.+/, url.slice(url.indexOf('#')));
2527
- }
2528
- exports._encode = encode;
2555
+ url = url.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, '');
2556
+ const {
2557
+ 1: base,
2558
+ 2: hash
2559
+ } = url.match(/^([^#]*)(.*)$/s);
2560
+ const {
2561
+ 1: path,
2562
+ 2: query
2563
+ } = base.replace(/(?:%(?:[0-9][a-f]|[a-f][0-9a-fA-F]|[A-F][0-9a-f]))+/g, str => str.toUpperCase()).match(/^([^?]*)(.*)$/s);
2564
+ return '' + path.replace(/(?:[^%[\]]|%(?![0-9A-F]{2}))+/ig, encodeURI) + query.replace(/(?!^)(?:[^%=&]|%(?![0-9A-F]{2}))+/ig, encodeURIComponent) + hash;
2565
+ }
2566
+ exports.encode = encode;
2529
2567
  class ReadonlyURL {
2530
2568
  constructor(source, base) {
2531
- this.source = source;
2532
- this.base = base;
2569
+ source = source.trim();
2570
+ base = base?.trim();
2533
2571
  switch (source.slice(0, source.lastIndexOf('://', 9) + 1).toLowerCase()) {
2534
2572
  case 'http:':
2535
2573
  case 'https:':
@@ -2544,60 +2582,66 @@ class ReadonlyURL {
2544
2582
  base = base.slice(0, i);
2545
2583
  }
2546
2584
  const j = base.indexOf('?');
2547
- if (i > -1 && source.indexOf('#') === -1) {
2585
+ if (j > -1 && source !== '' && source[0] !== '#') {
2548
2586
  base = base.slice(0, j);
2549
2587
  }
2550
2588
  }
2551
2589
  }
2552
- this.share = ReadonlyURL.get(source, base);
2590
+ this.cache = ReadonlyURL.get(source, base);
2591
+ this.params = undefined;
2592
+ this.source = source;
2593
+ this.base = base;
2553
2594
  }
2554
2595
  get href() {
2555
- return this.share.href ??= this.share.url.href;
2596
+ return this.cache.href ??= this.cache.url.href;
2556
2597
  }
2557
2598
  get resource() {
2558
- return this.share.resource ??= this.href.slice(0, -this.fragment.length - this.query.length || this.href.length) + this.search;
2599
+ return this.cache.resource ??= this.href.slice(0, this.href.search(/[?#]|$/)) + this.search;
2559
2600
  }
2560
2601
  get origin() {
2561
- return this.share.origin ??= this.share.url.origin;
2602
+ return this.cache.origin ??= this.cache.url.origin;
2603
+ }
2604
+ get scheme() {
2605
+ return this.cache.scheme ??= this.protocol.slice(0, -1);
2562
2606
  }
2563
2607
  get protocol() {
2564
- return this.share.protocol ??= this.share.url.protocol;
2608
+ return this.cache.protocol ??= this.cache.url.protocol;
2565
2609
  }
2566
2610
  get username() {
2567
- return this.share.username ??= this.share.url.username;
2611
+ return this.cache.username ??= this.cache.url.username;
2568
2612
  }
2569
2613
  get password() {
2570
- return this.share.password ??= this.share.url.password;
2614
+ return this.cache.password ??= this.cache.url.password;
2571
2615
  }
2572
2616
  get host() {
2573
- return this.share.host ??= this.share.url.host;
2617
+ return this.cache.host ??= this.cache.url.host;
2574
2618
  }
2575
2619
  get hostname() {
2576
- return this.share.hostname ??= this.share.url.hostname;
2620
+ return this.cache.hostname ??= this.cache.url.hostname;
2577
2621
  }
2578
2622
  get port() {
2579
- return this.share.port ??= this.share.url.port;
2623
+ return this.cache.port ??= this.cache.url.port;
2580
2624
  }
2581
2625
  get path() {
2582
- return this.share.path ??= `${this.pathname}${this.search}`;
2626
+ return this.cache.path ??= `${this.pathname}${this.search}`;
2583
2627
  }
2584
2628
  get pathname() {
2585
- return this.share.pathname ??= this.share.url.pathname;
2629
+ return this.cache.pathname ??= this.cache.url.pathname;
2586
2630
  }
2587
2631
  get search() {
2588
- return this.share.search ??= this.share.url.search;
2632
+ return this.cache.search ??= this.cache.url.search;
2589
2633
  }
2590
2634
  get query() {
2591
- return this.share.query ??= this.search || this.href[this.href.length - this.fragment.length - 1] === '?' && '?' || '';
2635
+ return this.cache.query ??= this.search || this.href[this.href.length - this.fragment.length - 1] === '?' && '?' || '';
2592
2636
  }
2593
2637
  get hash() {
2594
- return this.share.hash ??= this.share.url.hash;
2638
+ return this.cache.hash ??= this.cache.url.hash;
2595
2639
  }
2596
2640
  get fragment() {
2597
- return this.share.fragment ??= this.hash || this.href[this.href.length - 1] === '#' && '#' || '';
2641
+ return this.cache.fragment ??= this.hash || this.href[this.href.length - 1] === '#' && '#' || '';
2598
2642
  }
2599
2643
  get searchParams() {
2600
- return this.params ??= new URLSearchParams(this.search);
2644
+ return this.params ??= new ReadonlyURLSearchParams(this.search);
2601
2645
  }
2602
2646
  toString() {
2603
2647
  return this.href;
@@ -2614,6 +2658,26 @@ exports.ReadonlyURL = ReadonlyURL;
2614
2658
  ReadonlyURL.get = (0, memoize_1.memoize)((url, base) => ({
2615
2659
  url: new __webpack_require__.g.URL(url, base)
2616
2660
  }), (url, base = '') => `${base.indexOf('\n') > -1 ? base.replace(/\n+/g, '') : base}\n${url}`, new cache_1.Cache(10000));
2661
+ class ReadonlyURLSearchParams extends URLSearchParams {
2662
+ append(name, value) {
2663
+ this.sort();
2664
+ name;
2665
+ value;
2666
+ }
2667
+ delete(name, value) {
2668
+ this.sort();
2669
+ name;
2670
+ value;
2671
+ }
2672
+ set(name, value) {
2673
+ this.sort();
2674
+ name;
2675
+ value;
2676
+ }
2677
+ sort() {
2678
+ throw new Error('Spica: URL: Cannot use mutable methods with ReadonlyURLSearchParams');
2679
+ }
2680
+ }
2617
2681
 
2618
2682
  /***/ }),
2619
2683
 
@@ -4159,11 +4223,12 @@ Object.defineProperty(exports, "__esModule", ({
4159
4223
  }));
4160
4224
  exports.caches = void 0;
4161
4225
  const cache_1 = __webpack_require__(9210);
4226
+ const clock_1 = __webpack_require__(7681);
4162
4227
  // For rerendering in editing.
4163
4228
  exports.caches = {
4164
- code: new cache_1.Cache(1000),
4165
- math: new cache_1.Cache(10000),
4166
- media: new cache_1.Cache(100)
4229
+ code: new clock_1.Clock(1000),
4230
+ math: new cache_1.Cache(1000),
4231
+ media: new clock_1.Clock(100)
4167
4232
  };
4168
4233
 
4169
4234
  /***/ }),
@@ -7310,31 +7375,31 @@ function build(syntax, marker, splitter = '') {
7310
7375
  }
7311
7376
  }
7312
7377
  };
7313
- function* proc(defs, note) {
7314
- const {
7315
- children
7316
- } = note;
7317
- const size = defs.size;
7318
- let count = 0;
7319
- let length = children.length;
7320
- I: for (const [key, def] of defs) {
7321
- defs.delete(key);
7322
- ++count;
7323
- while (length > size) {
7324
- const node = children[count - 1];
7325
- if (equal(node, def)) continue I;
7326
- yield note.removeChild(node);
7327
- --length;
7328
- }
7329
- const node = count <= length ? children[count - 1] : null;
7330
- if (node && equal(node, def)) continue;
7331
- yield note.insertBefore(def, node);
7332
- ++length;
7333
- }
7378
+ }
7379
+ function* proc(defs, note) {
7380
+ const {
7381
+ children
7382
+ } = note;
7383
+ const size = defs.size;
7384
+ let count = 0;
7385
+ let length = children.length;
7386
+ I: for (const [key, def] of defs) {
7387
+ defs.delete(key);
7388
+ ++count;
7334
7389
  while (length > size) {
7335
- yield note.removeChild(children[size]);
7390
+ const node = children[count - 1];
7391
+ if (equal(node, def)) continue I;
7392
+ yield note.removeChild(node);
7336
7393
  --length;
7337
7394
  }
7395
+ const node = count <= length ? children[count - 1] : null;
7396
+ if (node && equal(node, def)) continue;
7397
+ yield note.insertBefore(def, node);
7398
+ ++length;
7399
+ }
7400
+ while (length > size) {
7401
+ yield note.removeChild(children[size]);
7402
+ --length;
7338
7403
  }
7339
7404
  }
7340
7405
  function equal(a, b) {
@@ -8530,7 +8595,7 @@ function unlink(h) {
8530
8595
  /***/ 3252:
8531
8596
  /***/ (function(module) {
8532
8597
 
8533
- /*! typed-dom v0.0.336 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */
8598
+ /*! typed-dom v0.0.348 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */
8534
8599
  (function webpackUniversalModuleDefinition(root, factory) {
8535
8600
  if(true)
8536
8601
  module.exports = factory();
@@ -8590,17 +8655,38 @@ Object.defineProperty(exports, "__esModule", ({
8590
8655
  exports.reduce = exports.memoize = void 0;
8591
8656
  const alias_1 = __nested_webpack_require_3150__(5406);
8592
8657
  const compare_1 = __nested_webpack_require_3150__(5529);
8593
- function memoize(f, identify = (...as) => as[0], memory) {
8594
- if (typeof identify === 'object') return memoize(f, undefined, identify);
8595
- return (0, alias_1.isArray)(memory) || memory?.constructor === Object ? memoizeRecord(f, identify, memory) : memoizeDict(f, identify, memory ?? new Map());
8658
+ function memoize(f, identify, memory) {
8659
+ if (typeof identify === 'object') {
8660
+ memory = identify;
8661
+ identify = undefined;
8662
+ }
8663
+ identify ??= (...as) => as[0];
8664
+ switch (true) {
8665
+ case (0, alias_1.isArray)(memory):
8666
+ return memoizeArray(f, identify, memory);
8667
+ case memory?.constructor === Object:
8668
+ return memoizeObject(f, identify, memory);
8669
+ default:
8670
+ return memoizeDict(f, identify, memory ?? new Map());
8671
+ }
8596
8672
  }
8597
8673
  exports.memoize = memoize;
8598
- function memoizeRecord(f, identify, memory) {
8674
+ function memoizeArray(f, identify, memory) {
8675
+ return (...as) => {
8676
+ const b = identify(...as);
8677
+ let z = memory[b];
8678
+ if (z !== undefined) return z;
8679
+ z = f(...as);
8680
+ memory[b] = z;
8681
+ return z;
8682
+ };
8683
+ }
8684
+ function memoizeObject(f, identify, memory) {
8599
8685
  let nullable = false;
8600
8686
  return (...as) => {
8601
8687
  const b = identify(...as);
8602
8688
  let z = memory[b];
8603
- if (z !== undefined || nullable && memory[b] !== undefined) return z;
8689
+ if (z !== undefined || nullable && b in memory) return z;
8604
8690
  z = f(...as);
8605
8691
  nullable ||= z === undefined;
8606
8692
  memory[b] = z;
@@ -8636,7 +8722,7 @@ exports.reduce = reduce;
8636
8722
  /***/ }),
8637
8723
 
8638
8724
  /***/ 7521:
8639
- /***/ ((__unused_webpack_module, exports, __nested_webpack_require_4668__) => {
8725
+ /***/ ((__unused_webpack_module, exports, __nested_webpack_require_5013__) => {
8640
8726
 
8641
8727
 
8642
8728
 
@@ -8644,10 +8730,11 @@ Object.defineProperty(exports, "__esModule", ({
8644
8730
  value: true
8645
8731
  }));
8646
8732
  exports.defrag = exports.prepend = exports.append = exports.isChildren = exports.define = exports.element = exports.text = exports.math = exports.svg = exports.html = exports.frag = exports.shadow = void 0;
8647
- const alias_1 = __nested_webpack_require_4668__(5406);
8648
- const memoize_1 = __nested_webpack_require_4668__(1808);
8733
+ const alias_1 = __nested_webpack_require_5013__(5406);
8734
+ const memoize_1 = __nested_webpack_require_5013__(1808);
8649
8735
  var caches;
8650
8736
  (function (caches) {
8737
+ // Closed only.
8651
8738
  caches.shadows = new WeakMap();
8652
8739
  caches.shadow = (0, memoize_1.memoize)((el, opts) => el.attachShadow(opts), caches.shadows);
8653
8740
  caches.fragment = document.createDocumentFragment();
@@ -8659,7 +8746,7 @@ function shadow(el, opts, children, factory = exports.html) {
8659
8746
  if (isChildren(opts)) return shadow(el, undefined, opts, factory);
8660
8747
  return defineChildren(!opts ? el.shadowRoot ?? caches.shadows.get(el) ?? el.attachShadow({
8661
8748
  mode: 'open'
8662
- }) : opts.mode === 'open' ? el.shadowRoot ?? el.attachShadow(opts) : caches.shadows.get(el) ?? caches.shadow(el, opts), children);
8749
+ }) : opts.mode === 'open' ? el.shadowRoot ?? el.attachShadow(opts) : caches.shadow(el, opts), children);
8663
8750
  }
8664
8751
  exports.shadow = shadow;
8665
8752
  function frag(children) {
@@ -8680,7 +8767,7 @@ function element(context, ns) {
8680
8767
  }
8681
8768
  exports.element = element;
8682
8769
  function elem(context, ns, tag, attrs) {
8683
- if (!('createElement' in context)) throw new Error(`TypedDOM: Scoped custom elements are not supported on this browser`);
8770
+ if (!('createElement' in context)) throw new Error(`Typed-DOM: Scoped custom elements are not supported on this browser`);
8684
8771
  const opts = 'is' in attrs ? {
8685
8772
  is: attrs['is']
8686
8773
  } : undefined;
@@ -8731,10 +8818,10 @@ function defineAttrs(el, attrs) {
8731
8818
  }
8732
8819
  continue;
8733
8820
  case 'function':
8734
- if (name.length < 3) throw new Error(`TypedDOM: Attribute names for event listeners must have an event name but got "${name}"`);
8821
+ if (name.length < 3) throw new Error(`Typed-DOM: Attribute names for event listeners must have an event name but got "${name}"`);
8735
8822
  const names = name.split(/\s+/);
8736
8823
  for (const name of names) {
8737
- if (!name.startsWith('on')) throw new Error(`TypedDOM: Attribute names for event listeners must start with "on" but got "${name}"`);
8824
+ if (!name.startsWith('on')) throw new Error(`Typed-DOM: Attribute names for event listeners must start with "on" but got "${name}"`);
8738
8825
  const type = name.slice(2).toLowerCase();
8739
8826
  el.addEventListener(type, value, {
8740
8827
  passive: ['wheel', 'mousewheel', 'touchstart', 'touchmove', 'touchend', 'touchcancel'].includes(type)
@@ -8766,7 +8853,7 @@ function defineChildren(node, children) {
8766
8853
  if (children === undefined) return node;
8767
8854
  if (typeof children === 'string') {
8768
8855
  node.textContent = children;
8769
- } else if ((0, alias_1.isArray)(children) && !node.firstChild) {
8856
+ } else if (((0, alias_1.isArray)(children) || !(Symbol.iterator in children)) && !node.firstChild) {
8770
8857
  for (let i = 0; i < children.length; ++i) {
8771
8858
  const child = children[i];
8772
8859
  typeof child === 'object' ? node.appendChild(child) : node.append(child);
@@ -8784,6 +8871,11 @@ function append(node, children) {
8784
8871
  if (children === undefined) return node;
8785
8872
  if (typeof children === 'string') {
8786
8873
  node.append(children);
8874
+ } else if ((0, alias_1.isArray)(children) || !(Symbol.iterator in children)) {
8875
+ for (let i = 0; i < children.length; ++i) {
8876
+ const child = children[i];
8877
+ typeof child === 'object' ? node.appendChild(child) : node.append(child);
8878
+ }
8787
8879
  } else {
8788
8880
  for (const child of children) {
8789
8881
  typeof child === 'object' ? node.appendChild(child) : node.append(child);
@@ -8796,6 +8888,11 @@ function prepend(node, children) {
8796
8888
  if (children === undefined) return node;
8797
8889
  if (typeof children === 'string') {
8798
8890
  node.prepend(children);
8891
+ } else if ((0, alias_1.isArray)(children) || !(Symbol.iterator in children)) {
8892
+ for (let i = 0; i < children.length; ++i) {
8893
+ const child = children[i];
8894
+ typeof child === 'object' ? node.insertBefore(child, null) : node.prepend(child);
8895
+ }
8799
8896
  } else {
8800
8897
  for (const child of children) {
8801
8898
  typeof child === 'object' ? node.insertBefore(child, null) : node.prepend(child);
@@ -8829,7 +8926,7 @@ exports.defrag = defrag;
8829
8926
  /******/ var __webpack_module_cache__ = {};
8830
8927
  /******/
8831
8928
  /******/ // The require function
8832
- /******/ function __nested_webpack_require_11654__(moduleId) {
8929
+ /******/ function __nested_webpack_require_12534__(moduleId) {
8833
8930
  /******/ // Check if module is in cache
8834
8931
  /******/ var cachedModule = __webpack_module_cache__[moduleId];
8835
8932
  /******/ if (cachedModule !== undefined) {
@@ -8843,7 +8940,7 @@ exports.defrag = defrag;
8843
8940
  /******/ };
8844
8941
  /******/
8845
8942
  /******/ // Execute the module function
8846
- /******/ __webpack_modules__[moduleId](module, module.exports, __nested_webpack_require_11654__);
8943
+ /******/ __webpack_modules__[moduleId](module, module.exports, __nested_webpack_require_12534__);
8847
8944
  /******/
8848
8945
  /******/ // Return the exports of the module
8849
8946
  /******/ return module.exports;
@@ -8854,7 +8951,7 @@ exports.defrag = defrag;
8854
8951
  /******/ // startup
8855
8952
  /******/ // Load entry module and return exports
8856
8953
  /******/ // This entry module is referenced by other modules so it can't be inlined
8857
- /******/ var __nested_webpack_exports__ = __nested_webpack_require_11654__(7521);
8954
+ /******/ var __nested_webpack_exports__ = __nested_webpack_require_12534__(7521);
8858
8955
  /******/
8859
8956
  /******/ return __nested_webpack_exports__;
8860
8957
  /******/ })()
@@ -8866,7 +8963,7 @@ exports.defrag = defrag;
8866
8963
  /***/ 6120:
8867
8964
  /***/ (function(module) {
8868
8965
 
8869
- /*! typed-dom v0.0.336 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */
8966
+ /*! typed-dom v0.0.348 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */
8870
8967
  (function webpackUniversalModuleDefinition(root, factory) {
8871
8968
  if(true)
8872
8969
  module.exports = factory();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.280.7",
3
+ "version": "0.280.8",
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",
@@ -27,37 +27,39 @@
27
27
  "NOTICE",
28
28
  "LICENSE"
29
29
  ],
30
+ "dependencies": {
31
+ "spica": "0.0.761"
32
+ },
30
33
  "devDependencies": {
31
- "@types/dompurify": "3.0.2",
32
- "@types/jquery": "3.5.16",
33
- "@types/mathjax": "0.0.37",
34
- "@types/mocha": "10.0.1",
35
- "@types/power-assert": "1.5.8",
36
- "@types/prismjs": "1.26.0",
37
- "@typescript-eslint/parser": "^5.59.9",
38
- "babel-loader": "^9.1.2",
34
+ "@types/dompurify": "3.0.4",
35
+ "@types/jquery": "3.5.26",
36
+ "@types/mathjax": "0.0.39",
37
+ "@types/mocha": "10.0.3",
38
+ "@types/power-assert": "1.5.10",
39
+ "@types/prismjs": "1.26.2",
40
+ "@typescript-eslint/parser": "^6.10.0",
41
+ "babel-loader": "^9.1.3",
39
42
  "babel-plugin-unassert": "^3.2.0",
40
- "concurrently": "^8.1.0",
41
- "eslint": "^8.42.0",
43
+ "concurrently": "^8.2.2",
44
+ "eslint": "^8.53.0",
42
45
  "eslint-plugin-redos": "^4.4.5",
43
46
  "eslint-webpack-plugin": "^4.0.1",
44
- "glob": "^10.2.7",
47
+ "glob": "^10.3.10",
45
48
  "karma": "^6.4.2",
46
49
  "karma-chrome-launcher": "^3.2.0",
47
- "karma-coverage": "^2.2.0",
50
+ "karma-coverage": "^2.2.1",
48
51
  "karma-firefox-launcher": "^2.1.2",
49
52
  "karma-mocha": "^2.0.1",
50
53
  "karma-power-assert": "^1.0.0",
51
54
  "mocha": "^10.2.0",
52
- "npm-check-updates": "^16.10.12",
53
- "semver": "^7.5.1",
54
- "spica": "0.0.732",
55
- "ts-loader": "^9.4.3",
56
- "typed-dom": "0.0.336",
57
- "typescript": "5.1.3",
58
- "webpack": "^5.85.1",
59
- "webpack-cli": "^5.1.3",
60
- "webpack-merge": "^5.9.0"
55
+ "npm-check-updates": "^16.14.6",
56
+ "semver": "^7.5.4",
57
+ "ts-loader": "^9.5.0",
58
+ "typed-dom": "0.0.348",
59
+ "typescript": "5.2.2",
60
+ "webpack": "^5.89.0",
61
+ "webpack-cli": "^5.1.4",
62
+ "webpack-merge": "^5.10.0"
61
63
  },
62
64
  "scripts": {
63
65
  "update": "ncu -u && npm i --no-shrinkwrap && bundle update",
@@ -1,10 +1,11 @@
1
1
  import { Caches } from '../../..';
2
2
  import { Cache } from 'spica/cache';
3
+ import { Clock } from 'spica/clock';
3
4
 
4
5
  // For rerendering in editing.
5
6
 
6
7
  export const caches: Caches = {
7
- code: new Cache<string, HTMLElement>(1000),
8
- math: new Cache<string, HTMLElement>(10000),
9
- media: new Cache<string, HTMLElement>(100),
8
+ code: new Clock<string, HTMLElement>(1000),
9
+ math: new Cache<string, HTMLElement>(1000),
10
+ media: new Clock<string, HTMLElement>(100),
10
11
  } as const;
@@ -180,37 +180,37 @@ function build(
180
180
  }
181
181
  }
182
182
  }
183
+ }
183
184
 
184
- function* proc(defs: Map<string, HTMLLIElement>, note: HTMLOListElement): Generator<HTMLLIElement | undefined, undefined, undefined> {
185
- const { children } = note;
186
- const size = defs.size;
187
- let count = 0;
188
- let length = children.length;
189
- I:
190
- for (const [key, def] of defs) {
191
- defs.delete(key);
192
- ++count;
193
- while (length > size) {
194
- const node = children[count - 1] as HTMLLIElement;
195
- if (equal(node, def)) continue I;
196
- yield note.removeChild(node);
197
- --length;
198
- assert(children.length === length);
199
- }
200
- const node = count <= length
201
- ? children[count - 1]
202
- : null;
203
- if (node && equal(node, def)) continue;
204
- assert(def.parentNode !== note);
205
- yield note.insertBefore(def, node);
206
- ++length;
207
- assert(children.length === length);
208
- }
185
+ function* proc(defs: Map<string, HTMLLIElement>, note: HTMLOListElement): Generator<HTMLLIElement | undefined, undefined, undefined> {
186
+ const { children } = note;
187
+ const size = defs.size;
188
+ let count = 0;
189
+ let length = children.length;
190
+ I:
191
+ for (const [key, def] of defs) {
192
+ defs.delete(key);
193
+ ++count;
209
194
  while (length > size) {
210
- yield note.removeChild(children[size] as HTMLLIElement);
195
+ const node = children[count - 1] as HTMLLIElement;
196
+ if (equal(node, def)) continue I;
197
+ yield note.removeChild(node);
211
198
  --length;
212
199
  assert(children.length === length);
213
200
  }
201
+ const node = count <= length
202
+ ? children[count - 1]
203
+ : null;
204
+ if (node && equal(node, def)) continue;
205
+ assert(def.parentNode !== note);
206
+ yield note.insertBefore(def, node);
207
+ ++length;
208
+ assert(children.length === length);
209
+ }
210
+ while (length > size) {
211
+ yield note.removeChild(children[size] as HTMLLIElement);
212
+ --length;
213
+ assert(children.length === length);
214
214
  }
215
215
  }
216
216