securemark 0.260.5 → 0.260.6
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 +4 -0
- package/dist/index.js +161 -89
- package/package.json +5 -5
- package/src/parser/block/reply/cite.test.ts +5 -0
- package/src/parser/block/reply/cite.ts +5 -4
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.260.
|
|
1
|
+
/*! securemark v0.260.6 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("DOMPurify"), require("Prism"));
|
|
@@ -64,9 +64,9 @@ __exportStar(__webpack_require__(256), exports);
|
|
|
64
64
|
Object.defineProperty(exports, "__esModule", ({
|
|
65
65
|
value: true
|
|
66
66
|
}));
|
|
67
|
-
exports.ObjectSetPrototypeOf = exports.ObjectGetPrototypeOf = exports.ObjectCreate = exports.ObjectAssign = exports.toString = exports.isEnumerable = exports.isPrototypeOf = exports.hasOwnProperty = exports.isArray = exports.sign = exports.round = exports.random = exports.min = exports.max = exports.floor = exports.ceil = exports.abs = exports.parseInt = exports.parseFloat = exports.isSafeInteger = exports.isNaN = exports.isInteger = exports.isFinite = exports[NaN] = void 0;
|
|
67
|
+
exports.ObjectSetPrototypeOf = exports.ObjectGetPrototypeOf = exports.ObjectCreate = exports.ObjectAssign = exports.toString = exports.isEnumerable = exports.isPrototypeOf = exports.hasOwnProperty = exports.isArray = exports.sqrt = exports.log = exports.tan = exports.cos = exports.sign = exports.round = exports.random = exports.min = exports.max = exports.floor = exports.ceil = exports.abs = exports.parseInt = exports.parseFloat = exports.isSafeInteger = exports.isNaN = exports.isInteger = exports.isFinite = exports[NaN] = void 0;
|
|
68
68
|
exports[NaN] = Number.NaN, exports.isFinite = Number.isFinite, exports.isInteger = Number.isInteger, exports.isNaN = Number.isNaN, exports.isSafeInteger = Number.isSafeInteger, exports.parseFloat = Number.parseFloat, exports.parseInt = Number.parseInt;
|
|
69
|
-
exports.abs = Math.abs, exports.ceil = Math.ceil, exports.floor = Math.floor, exports.max = Math.max, exports.min = Math.min, exports.random = Math.random, exports.round = Math.round, exports.sign = Math.sign;
|
|
69
|
+
exports.abs = Math.abs, exports.ceil = Math.ceil, exports.floor = Math.floor, exports.max = Math.max, exports.min = Math.min, exports.random = Math.random, exports.round = Math.round, exports.sign = Math.sign, exports.cos = Math.cos, exports.tan = Math.tan, exports.log = Math.log, exports.sqrt = Math.sqrt;
|
|
70
70
|
exports.isArray = Array.isArray;
|
|
71
71
|
exports.hasOwnProperty = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
|
|
72
72
|
exports.isPrototypeOf = Object.prototype.isPrototypeOf.call.bind(Object.prototype.isPrototypeOf);
|
|
@@ -356,6 +356,8 @@ exports.Cache = void 0;
|
|
|
356
356
|
|
|
357
357
|
const global_1 = __webpack_require__(4128);
|
|
358
358
|
|
|
359
|
+
const alias_1 = __webpack_require__(5406);
|
|
360
|
+
|
|
359
361
|
const clock_1 = __webpack_require__(7681);
|
|
360
362
|
|
|
361
363
|
const invlist_1 = __webpack_require__(7452);
|
|
@@ -364,20 +366,23 @@ const heap_1 = __webpack_require__(818);
|
|
|
364
366
|
|
|
365
367
|
const assign_1 = __webpack_require__(4401);
|
|
366
368
|
|
|
367
|
-
const tuple_1 = __webpack_require__(5341);
|
|
368
|
-
|
|
369
369
|
class Cache {
|
|
370
370
|
constructor(capacity, opts = {}) {
|
|
371
371
|
this.settings = {
|
|
372
|
+
window: 0,
|
|
372
373
|
capacity: 0,
|
|
373
374
|
space: global_1.Infinity,
|
|
374
375
|
age: global_1.Infinity,
|
|
375
376
|
earlyExpiring: false,
|
|
376
|
-
limit: 950,
|
|
377
377
|
capture: {
|
|
378
378
|
delete: true,
|
|
379
379
|
clear: true
|
|
380
|
-
}
|
|
380
|
+
},
|
|
381
|
+
resolution: 1,
|
|
382
|
+
offset: 0,
|
|
383
|
+
block: 20,
|
|
384
|
+
sweep: 10,
|
|
385
|
+
limit: 950
|
|
381
386
|
};
|
|
382
387
|
this.overlap = 0;
|
|
383
388
|
this.SIZE = 0;
|
|
@@ -387,31 +392,8 @@ class Cache {
|
|
|
387
392
|
LFU: new invlist_1.List()
|
|
388
393
|
};
|
|
389
394
|
this.expiries = new heap_1.Heap((a, b) => a.value.expiry - b.value.expiry);
|
|
390
|
-
this.
|
|
391
|
-
|
|
392
|
-
LFU: (0, tuple_1.tuple)(0, 0),
|
|
393
|
-
|
|
394
|
-
slide() {
|
|
395
|
-
const {
|
|
396
|
-
LRU,
|
|
397
|
-
LFU
|
|
398
|
-
} = this;
|
|
399
|
-
LRU[1] = LRU[0];
|
|
400
|
-
LRU[0] = 0;
|
|
401
|
-
LFU[1] = LFU[0];
|
|
402
|
-
LFU[0] = 0;
|
|
403
|
-
},
|
|
404
|
-
|
|
405
|
-
clear() {
|
|
406
|
-
const {
|
|
407
|
-
LRU,
|
|
408
|
-
LFU
|
|
409
|
-
} = this;
|
|
410
|
-
LRU[0] = LRU[1] = 0;
|
|
411
|
-
LFU[0] = LFU[1] = 0;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
};
|
|
395
|
+
this.misses = 0;
|
|
396
|
+
this.sweep = 0;
|
|
415
397
|
this.ratio = 500;
|
|
416
398
|
|
|
417
399
|
if (typeof capacity === 'object') {
|
|
@@ -419,15 +401,19 @@ class Cache {
|
|
|
419
401
|
capacity = opts.capacity ?? 0;
|
|
420
402
|
}
|
|
421
403
|
|
|
422
|
-
(0, assign_1.extend)(this.settings, opts, {
|
|
404
|
+
const settings = (0, assign_1.extend)(this.settings, opts, {
|
|
423
405
|
capacity
|
|
424
406
|
});
|
|
425
|
-
this.capacity =
|
|
407
|
+
this.capacity = settings.capacity;
|
|
426
408
|
if (this.capacity >= 1 === false) throw new Error(`Spica: Cache: Capacity must be 1 or more.`);
|
|
427
|
-
this.
|
|
428
|
-
this.
|
|
429
|
-
this.
|
|
430
|
-
this.
|
|
409
|
+
this.window = settings.window || this.capacity;
|
|
410
|
+
if (this.window * 1000 < this.capacity) throw new Error(`Spica: Cache: Window must be 0.1% of capacity or more.`);
|
|
411
|
+
this.space = settings.space;
|
|
412
|
+
this.block = settings.block;
|
|
413
|
+
this.limit = settings.limit;
|
|
414
|
+
this.earlyExpiring = settings.earlyExpiring;
|
|
415
|
+
this.disposer = settings.disposer;
|
|
416
|
+
this.stats = new Stats(this.window, settings.resolution, settings.offset);
|
|
431
417
|
}
|
|
432
418
|
|
|
433
419
|
get length() {
|
|
@@ -452,7 +438,7 @@ class Cache {
|
|
|
452
438
|
|
|
453
439
|
ensure(margin, skip) {
|
|
454
440
|
let size = skip?.value.size ?? 0;
|
|
455
|
-
if (margin - size <= 0) return;
|
|
441
|
+
if (margin - size <= 0) return true;
|
|
456
442
|
const {
|
|
457
443
|
LRU,
|
|
458
444
|
LFU
|
|
@@ -474,7 +460,6 @@ class Cache {
|
|
|
474
460
|
target = LFU.last !== skip ? LFU.last : LFU.length >= 2 ? LFU.last.prev : skip;
|
|
475
461
|
|
|
476
462
|
if (target !== skip) {
|
|
477
|
-
if (this.ratio > 500) break;
|
|
478
463
|
LRU.unshiftNode(target);
|
|
479
464
|
++this.overlap;
|
|
480
465
|
}
|
|
@@ -482,6 +467,18 @@ class Cache {
|
|
|
482
467
|
// fallthrough
|
|
483
468
|
|
|
484
469
|
default:
|
|
470
|
+
if (this.misses * 100 > LRU.length * this.block) {
|
|
471
|
+
this.sweep ||= LRU.length * this.settings.sweep / 100 + 1 | 0;
|
|
472
|
+
|
|
473
|
+
if (this.sweep > 0) {
|
|
474
|
+
LRU.head = LRU.head.next.next;
|
|
475
|
+
--this.sweep;
|
|
476
|
+
this.sweep ||= -(0, alias_1.round)(LRU.length * this.settings.sweep / 100 * 99 / 100);
|
|
477
|
+
} else {
|
|
478
|
+
++this.sweep;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
485
482
|
target = LRU.last !== skip ? LRU.last : LRU.length >= 2 ? LRU.last.prev : LFU.last;
|
|
486
483
|
}
|
|
487
484
|
|
|
@@ -489,6 +486,8 @@ class Cache {
|
|
|
489
486
|
skip = skip?.list && skip;
|
|
490
487
|
size = skip?.value.size ?? 0;
|
|
491
488
|
}
|
|
489
|
+
|
|
490
|
+
return !!skip?.list;
|
|
492
491
|
}
|
|
493
492
|
|
|
494
493
|
put(key, value, {
|
|
@@ -503,10 +502,9 @@ class Cache {
|
|
|
503
502
|
const expiry = age === global_1.Infinity ? global_1.Infinity : (0, clock_1.now)() + age;
|
|
504
503
|
const node = this.memory.get(key);
|
|
505
504
|
|
|
506
|
-
if (node) {
|
|
505
|
+
if (node && this.ensure(size, node)) {
|
|
507
506
|
const val = node.value.value;
|
|
508
507
|
const index = node.value;
|
|
509
|
-
this.ensure(size, node);
|
|
510
508
|
this.SIZE += size - index.size;
|
|
511
509
|
index.size = size;
|
|
512
510
|
index.expiry = expiry;
|
|
@@ -550,10 +548,16 @@ class Cache {
|
|
|
550
548
|
|
|
551
549
|
get(key) {
|
|
552
550
|
const node = this.memory.get(key);
|
|
553
|
-
|
|
551
|
+
|
|
552
|
+
if (!node) {
|
|
553
|
+
++this.misses;
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
|
|
554
557
|
const expiry = node.value.expiry;
|
|
555
558
|
|
|
556
559
|
if (expiry !== global_1.Infinity && expiry < (0, clock_1.now)()) {
|
|
560
|
+
++this.misses;
|
|
557
561
|
this.evict(node, true);
|
|
558
562
|
return;
|
|
559
563
|
} // Optimization for memoize.
|
|
@@ -561,7 +565,9 @@ class Cache {
|
|
|
561
565
|
|
|
562
566
|
if (this.capacity > 3 && node === node.list.head) return node.value.value;
|
|
563
567
|
this.access(node);
|
|
564
|
-
this.
|
|
568
|
+
this.adjust();
|
|
569
|
+
this.misses &&= 0;
|
|
570
|
+
this.sweep = 0;
|
|
565
571
|
return node.value.value;
|
|
566
572
|
}
|
|
567
573
|
|
|
@@ -588,6 +594,8 @@ class Cache {
|
|
|
588
594
|
}
|
|
589
595
|
|
|
590
596
|
clear() {
|
|
597
|
+
this.misses = 0;
|
|
598
|
+
this.sweep = 0;
|
|
591
599
|
this.overlap = 0;
|
|
592
600
|
this.SIZE = 0;
|
|
593
601
|
this.ratio = 500;
|
|
@@ -620,31 +628,26 @@ class Cache {
|
|
|
620
628
|
return;
|
|
621
629
|
}
|
|
622
630
|
|
|
623
|
-
|
|
624
|
-
const {
|
|
625
|
-
LRU,
|
|
626
|
-
LFU
|
|
627
|
-
} = this.stats;
|
|
631
|
+
adjust() {
|
|
628
632
|
const {
|
|
629
633
|
capacity,
|
|
630
634
|
ratio,
|
|
631
635
|
limit,
|
|
636
|
+
stats,
|
|
632
637
|
indexes
|
|
633
638
|
} = this;
|
|
634
|
-
|
|
635
|
-
const total = LRU[0] + LFU[0];
|
|
636
|
-
total === window && this.stats.slide();
|
|
637
|
-
if (total * 1000 % capacity || !LRU[1] || !LFU[1]) return;
|
|
639
|
+
if (stats.subtotal() * 1000 % capacity || !stats.full()) return;
|
|
638
640
|
const lenR = indexes.LRU.length;
|
|
639
641
|
const lenF = indexes.LFU.length;
|
|
640
|
-
const
|
|
641
|
-
const
|
|
642
|
-
const rateR0 =
|
|
643
|
-
const rateF0 =
|
|
644
|
-
const rateF1 =
|
|
642
|
+
const lenO = this.overlap;
|
|
643
|
+
const leverage = (lenF + lenO) * 1000 / (lenR + lenF) | 0;
|
|
644
|
+
const rateR0 = stats.rateLRU() * leverage;
|
|
645
|
+
const rateF0 = stats.rateLFU() * (1000 - leverage);
|
|
646
|
+
const rateF1 = stats.offset && stats.rateLFU(true) * (1000 - leverage); // 操作頻度を超えてキャッシュ比率を増減させても余剰比率の消化が追いつかず無駄
|
|
645
647
|
// LRUの下限設定ではLRU拡大の要否を迅速に判定できないためLFUのヒット率低下の検出で代替する
|
|
646
648
|
|
|
647
|
-
if (ratio > 0 && (rateR0 > rateF0 || rateF0 < rateF1 *
|
|
649
|
+
if (ratio > 0 && (rateR0 > rateF0 || stats.offset && rateF0 * 100 < rateF1 * (100 - stats.offset))) {
|
|
650
|
+
//rateR0 <= rateF0 && rateF0 * 100 < rateF1 * (100 - stats.offset) && console.debug(0);
|
|
648
651
|
if (lenR >= capacity * (1000 - ratio) / 1000) {
|
|
649
652
|
//ratio % 100 || ratio === 1000 || console.debug('-', ratio, LRU, LFU);
|
|
650
653
|
--this.ratio;
|
|
@@ -682,13 +685,100 @@ class Cache {
|
|
|
682
685
|
|
|
683
686
|
exports.Cache = Cache;
|
|
684
687
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
688
|
+
class Stats {
|
|
689
|
+
constructor(window, resolution, offset) {
|
|
690
|
+
this.window = window;
|
|
691
|
+
this.resolution = resolution;
|
|
692
|
+
this.offset = offset;
|
|
693
|
+
this.max = (0, alias_1.ceil)(this.resolution * (100 + this.offset) / 100) + 1;
|
|
694
|
+
this.LRU = [0];
|
|
695
|
+
this.LFU = [0];
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
get length() {
|
|
699
|
+
return this.LRU.length;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
full() {
|
|
703
|
+
return this.length === this.max;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
rateLRU(offset = false) {
|
|
707
|
+
return rate(this.window, this.LRU, this.LFU, +offset && this.offset);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
rateLFU(offset = false) {
|
|
711
|
+
return rate(this.window, this.LFU, this.LRU, +offset && this.offset);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
subtotal() {
|
|
715
|
+
const {
|
|
716
|
+
LRU,
|
|
717
|
+
LFU,
|
|
718
|
+
window,
|
|
719
|
+
resolution,
|
|
720
|
+
offset
|
|
721
|
+
} = this;
|
|
722
|
+
|
|
723
|
+
if (offset && LRU[0] + LFU[0] >= window * offset / 100) {
|
|
724
|
+
if (this.length === 1) {
|
|
725
|
+
this.slide();
|
|
726
|
+
} else {
|
|
727
|
+
LRU[1] += LRU[0];
|
|
728
|
+
LFU[1] += LFU[0];
|
|
729
|
+
LRU[0] = 0;
|
|
730
|
+
LFU[0] = 0;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
const subtotal = LRU[+offset && 1] + LFU[+offset && 1] || 0;
|
|
735
|
+
subtotal >= window / resolution && this.slide();
|
|
736
|
+
return LRU[0] + LFU[0];
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
slide() {
|
|
740
|
+
const {
|
|
741
|
+
LRU,
|
|
742
|
+
LFU,
|
|
743
|
+
max
|
|
744
|
+
} = this;
|
|
745
|
+
|
|
746
|
+
if (LRU.length === max) {
|
|
747
|
+
LRU.pop();
|
|
748
|
+
LFU.pop();
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
LRU.unshift(0);
|
|
752
|
+
LFU.unshift(0);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
clear() {
|
|
756
|
+
this.LRU = [0];
|
|
757
|
+
this.LFU = [0];
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
function rate(window, hits1, hits2, offset) {
|
|
763
|
+
let total = 0;
|
|
764
|
+
let hits = 0;
|
|
765
|
+
let ratio = 100;
|
|
766
|
+
|
|
767
|
+
for (let i = 0, len = hits1.length; i < len; ++i) {
|
|
768
|
+
const subtotal = hits1[i] + hits2[i];
|
|
769
|
+
if (subtotal === 0) continue;
|
|
770
|
+
offset = i + 1 === len ? 0 : offset;
|
|
771
|
+
const subratio = (0, alias_1.min)(subtotal * 100 / window, ratio) - offset;
|
|
772
|
+
offset = offset && subratio < 0 ? -subratio : 0;
|
|
773
|
+
if (subratio <= 0) continue;
|
|
774
|
+
const rate = window * subratio / subtotal;
|
|
775
|
+
total += subtotal * rate;
|
|
776
|
+
hits += hits1[i] * rate;
|
|
777
|
+
ratio -= subratio;
|
|
778
|
+
if (ratio <= 0) break;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
return hits * 10000 / total | 0;
|
|
692
782
|
}
|
|
693
783
|
|
|
694
784
|
/***/ }),
|
|
@@ -1671,25 +1761,6 @@ function random(len) {
|
|
|
1671
1761
|
|
|
1672
1762
|
/***/ }),
|
|
1673
1763
|
|
|
1674
|
-
/***/ 5341:
|
|
1675
|
-
/***/ ((__unused_webpack_module, exports) => {
|
|
1676
|
-
|
|
1677
|
-
"use strict";
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
Object.defineProperty(exports, "__esModule", ({
|
|
1681
|
-
value: true
|
|
1682
|
-
}));
|
|
1683
|
-
exports.tuple = void 0;
|
|
1684
|
-
|
|
1685
|
-
function tuple(...as) {
|
|
1686
|
-
return as;
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
|
-
exports.tuple = tuple;
|
|
1690
|
-
|
|
1691
|
-
/***/ }),
|
|
1692
|
-
|
|
1693
1764
|
/***/ 5177:
|
|
1694
1765
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1695
1766
|
|
|
@@ -5502,15 +5573,16 @@ const source_1 = __webpack_require__(6743);
|
|
|
5502
5573
|
|
|
5503
5574
|
const dom_1 = __webpack_require__(3252);
|
|
5504
5575
|
|
|
5505
|
-
exports.cite = (0, combinator_1.creation)(1, false, (0, combinator_1.line)((0, combinator_1.fmap)((0, combinator_1.validate)('>>', (0, combinator_1.reverse)((0, combinator_1.tails)([(0, source_1.str)(/^>*(?=>>[^>\s]
|
|
5576
|
+
exports.cite = (0, combinator_1.creation)(1, false, (0, combinator_1.line)((0, combinator_1.fmap)((0, combinator_1.validate)('>>', (0, combinator_1.reverse)((0, combinator_1.tails)([(0, source_1.str)(/^>*(?=>>[^>\s]+\s*$)/), (0, combinator_1.union)([anchor_1.anchor, // Subject page representation.
|
|
5506
5577
|
// リンクの実装は後で検討
|
|
5507
|
-
(0, combinator_1.focus)(/^>>\.
|
|
5578
|
+
(0, combinator_1.focus)(/^>>\.(?=\s*$)/, () => [[(0, dom_1.html)('a', {
|
|
5508
5579
|
class: 'anchor'
|
|
5509
|
-
}, '>>.')], '']), (0, combinator_1.focus)(/^>>#\S*
|
|
5580
|
+
}, '>>.')], '']), (0, combinator_1.focus)(/^>>#\S*(?=\s*$)/, ({
|
|
5510
5581
|
source
|
|
5511
5582
|
}) => [[(0, dom_1.html)('a', {
|
|
5512
5583
|
class: 'anchor'
|
|
5513
|
-
}, source)], '']),
|
|
5584
|
+
}, source)], '']), // Support all domains, but don't support IP(v6) addresses.
|
|
5585
|
+
(0, combinator_1.focus)(/^>>https?:\/\/[^\p{C}\p{S}\p{P}\s]\S*(?=\s*$)/u, ({
|
|
5514
5586
|
source
|
|
5515
5587
|
}) => [[(0, dom_1.html)('a', {
|
|
5516
5588
|
class: 'anchor',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "securemark",
|
|
3
|
-
"version": "0.260.
|
|
3
|
+
"version": "0.260.6",
|
|
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,7 +34,7 @@
|
|
|
34
34
|
"@types/mocha": "9.1.1",
|
|
35
35
|
"@types/power-assert": "1.5.8",
|
|
36
36
|
"@types/prismjs": "1.26.0",
|
|
37
|
-
"@typescript-eslint/parser": "^5.
|
|
37
|
+
"@typescript-eslint/parser": "^5.31.0",
|
|
38
38
|
"babel-loader": "^8.2.5",
|
|
39
39
|
"babel-plugin-unassert": "^3.2.0",
|
|
40
40
|
"concurrently": "^7.3.0",
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
"karma-mocha": "^2.0.1",
|
|
50
50
|
"karma-power-assert": "^1.0.0",
|
|
51
51
|
"mocha": "^10.0.0",
|
|
52
|
-
"npm-check-updates": "^
|
|
52
|
+
"npm-check-updates": "^16.0.3",
|
|
53
53
|
"semver": "^7.3.7",
|
|
54
|
-
"spica": "0.0.
|
|
54
|
+
"spica": "0.0.591",
|
|
55
55
|
"ts-loader": "^9.3.1",
|
|
56
56
|
"typed-dom": "^0.0.301",
|
|
57
57
|
"typescript": "4.7.4",
|
|
58
|
-
"webpack": "^5.
|
|
58
|
+
"webpack": "^5.74.0",
|
|
59
59
|
"webpack-cli": "^4.10.0",
|
|
60
60
|
"webpack-merge": "^5.8.0"
|
|
61
61
|
},
|
|
@@ -39,11 +39,16 @@ describe('Unit: parser/block/reply/cite', () => {
|
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('>>>0\n>>')), [['<span class="cite">>><a class="anchor" href="?at=0" data-depth="2">>0</a></span>', '<br>'], '>>']);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('>>>0\n>>1')), [['<span class="cite">>><a class="anchor" href="?at=0" data-depth="2">>0</a></span>', '<br>', '<span class="cite">><a class="anchor" href="?at=1" data-depth="1">>1</a></span>', '<br>'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('>>.')), [['<span class="cite">><a class="anchor" data-depth="1">>.</a></span>', '<br>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('>>. ')), [['<span class="cite">><a class="anchor" data-depth="1">>.</a></span>', '<br>'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('>>.\n')), [['<span class="cite">><a class="anchor" data-depth="1">>.</a></span>', '<br>'], '']);
|
|
42
44
|
assert.deepStrictEqual(inspect(parser('>>#')), [['<span class="cite">><a class="anchor" data-depth="1">>#</a></span>', '<br>'], '']);
|
|
45
|
+
assert.deepStrictEqual(inspect(parser('>>#\n')), [['<span class="cite">><a class="anchor" data-depth="1">>#</a></span>', '<br>'], '']);
|
|
43
46
|
assert.deepStrictEqual(inspect(parser('>>#a')), [['<span class="cite">><a class="anchor" data-depth="1">>#a</a></span>', '<br>'], '']);
|
|
44
47
|
assert.deepStrictEqual(inspect(parser('>>#index:a')), [['<span class="cite">><a class="anchor" data-depth="1">>#index:a</a></span>', '<br>'], '']);
|
|
45
48
|
assert.deepStrictEqual(inspect(parser('>>#:~:text=a')), [['<span class="cite">><a class="anchor" data-depth="1">>#:~:text=a</a></span>', '<br>'], '']);
|
|
46
49
|
assert.deepStrictEqual(inspect(parser('>>http://host')), [['<span class="cite">><a class="anchor" href="http://host" target="_blank" data-depth="1">>http://host</a></span>', '<br>'], '']);
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('>>http://host ')), [['<span class="cite">><a class="anchor" href="http://host" target="_blank" data-depth="1">>http://host</a></span>', '<br>'], '']);
|
|
51
|
+
assert.deepStrictEqual(inspect(parser('>>http://host\n')), [['<span class="cite">><a class="anchor" href="http://host" target="_blank" data-depth="1">>http://host</a></span>', '<br>'], '']);
|
|
47
52
|
assert.deepStrictEqual(inspect(parser('>>https://host')), [['<span class="cite">><a class="anchor" href="https://host" target="_blank" data-depth="1">>https://host</a></span>', '<br>'], '']);
|
|
48
53
|
});
|
|
49
54
|
|
|
@@ -7,14 +7,15 @@ import { html, define, defrag } from 'typed-dom/dom';
|
|
|
7
7
|
export const cite: ReplyParser.CiteParser = creation(1, false, line(fmap(validate(
|
|
8
8
|
'>>',
|
|
9
9
|
reverse(tails([
|
|
10
|
-
str(/^>*(?=>>[^>\s]
|
|
10
|
+
str(/^>*(?=>>[^>\s]+\s*$)/),
|
|
11
11
|
union([
|
|
12
12
|
anchor,
|
|
13
13
|
// Subject page representation.
|
|
14
14
|
// リンクの実装は後で検討
|
|
15
|
-
focus(/^>>\.
|
|
16
|
-
focus(/^>>#\S*
|
|
17
|
-
|
|
15
|
+
focus(/^>>\.(?=\s*$)/, () => [[html('a', { class: 'anchor' }, '>>.')], '']),
|
|
16
|
+
focus(/^>>#\S*(?=\s*$)/, ({ source }) => [[html('a', { class: 'anchor' }, source)], '']),
|
|
17
|
+
// Support all domains, but don't support IP(v6) addresses.
|
|
18
|
+
focus(/^>>https?:\/\/[^\p{C}\p{S}\p{P}\s]\S*(?=\s*$)/u, ({ source }) => [[html('a', { class: 'anchor', href: source.slice(2).trimEnd(), target: '_blank' }, source)], '']),
|
|
18
19
|
]),
|
|
19
20
|
]))),
|
|
20
21
|
([el, quotes = '']: [HTMLElement, string?]) => [
|