@xpadev-net/niconicomments 0.2.55 → 0.2.57
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/LICENSE +21 -21
- package/README.en.md +53 -53
- package/README.md +50 -50
- package/dist/bundle.d.ts +326 -301
- package/dist/bundle.js +563 -202
- package/package.json +42 -40
package/dist/bundle.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
niconicomments.js v0.2.
|
|
2
|
+
niconicomments.js v0.2.57
|
|
3
3
|
(c) 2021 xpadev-net https://xpadev.net
|
|
4
4
|
Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -48,6 +48,11 @@
|
|
|
48
48
|
setPlugins: setPlugins
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
+
let isDebug = false;
|
|
52
|
+
const setIsDebug = (val) => {
|
|
53
|
+
isDebug = val;
|
|
54
|
+
};
|
|
55
|
+
|
|
51
56
|
let defaultConfig;
|
|
52
57
|
const updateConfig = (config) => {
|
|
53
58
|
defaultConfig = config;
|
|
@@ -147,7 +152,7 @@
|
|
|
147
152
|
};
|
|
148
153
|
|
|
149
154
|
const hex2rgb = (hex) => {
|
|
150
|
-
if (hex.
|
|
155
|
+
if (hex.startsWith("#"))
|
|
151
156
|
hex = hex.slice(1);
|
|
152
157
|
if (hex.length === 3)
|
|
153
158
|
hex =
|
|
@@ -162,7 +167,7 @@
|
|
|
162
167
|
});
|
|
163
168
|
};
|
|
164
169
|
const hex2rgba = (hex) => {
|
|
165
|
-
if (hex.
|
|
170
|
+
if (hex.startsWith("#"))
|
|
166
171
|
hex = hex.slice(1);
|
|
167
172
|
if (hex.length === 4)
|
|
168
173
|
hex =
|
|
@@ -252,6 +257,7 @@
|
|
|
252
257
|
"mail",
|
|
253
258
|
"user_id",
|
|
254
259
|
"layer",
|
|
260
|
+
"is_my_post",
|
|
255
261
|
]),
|
|
256
262
|
comments: (i) => {
|
|
257
263
|
if (typeof i !== "object")
|
|
@@ -390,27 +396,30 @@
|
|
|
390
396
|
},
|
|
391
397
|
nicoScript: {
|
|
392
398
|
range: {
|
|
393
|
-
target: (i) => typeof i === "string" &&
|
|
399
|
+
target: (i) => typeof i === "string" &&
|
|
400
|
+
!!RegExp(/^(?:\u6295?\u30b3\u30e1|\u5168)$/).exec(i),
|
|
394
401
|
},
|
|
395
402
|
replace: {
|
|
396
|
-
range: (i) => typeof i === "string" && !!
|
|
403
|
+
range: (i) => typeof i === "string" && !!RegExp(/^[\u5358\u5168]$/).exec(i),
|
|
397
404
|
target: (i) => typeof i === "string" &&
|
|
398
|
-
!!
|
|
405
|
+
!!RegExp(/^(?:\u30b3\u30e1|\u6295\u30b3\u30e1|\u5168|\u542b\u3080|\u542b\u307e\u306a\u3044)$/).exec(i),
|
|
399
406
|
condition: (i) => typeof i === "string" &&
|
|
400
|
-
!!
|
|
407
|
+
!!RegExp(/^(?:\u90e8\u5206\u4e00\u81f4|\u5b8c\u5168\u4e00\u81f4)$/).exec(i),
|
|
401
408
|
},
|
|
402
409
|
},
|
|
403
410
|
comment: {
|
|
404
|
-
font: (i) => typeof i === "string" && !!
|
|
405
|
-
loc: (i) => typeof i === "string" && !!
|
|
406
|
-
size: (i) => typeof i === "string" && !!
|
|
411
|
+
font: (i) => typeof i === "string" && !!RegExp(/^(?:gothic|mincho|defont)$/).exec(i),
|
|
412
|
+
loc: (i) => typeof i === "string" && !!RegExp(/^(?:ue|naka|shita)$/).exec(i),
|
|
413
|
+
size: (i) => typeof i === "string" && !!RegExp(/^(?:big|medium|small)$/).exec(i),
|
|
407
414
|
command: {
|
|
408
|
-
key: (i) => typeof i === "string" &&
|
|
415
|
+
key: (i) => typeof i === "string" &&
|
|
416
|
+
!!RegExp(/^(?:full|ender|_live|invisible)$/).exec(i),
|
|
409
417
|
},
|
|
410
418
|
color: (i) => typeof i === "string" && Object.keys(colors).includes(i),
|
|
411
|
-
colorCode: (i) => typeof i === "string" &&
|
|
419
|
+
colorCode: (i) => typeof i === "string" &&
|
|
420
|
+
!!RegExp(/^#(?:[0-9a-z]{3}|[0-9a-z]{6})$/).exec(i),
|
|
412
421
|
colorCodeAllowAlpha: (i) => typeof i === "string" &&
|
|
413
|
-
!!
|
|
422
|
+
!!RegExp(/^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/).exec(i),
|
|
414
423
|
},
|
|
415
424
|
config: {
|
|
416
425
|
initOptions: (item) => {
|
|
@@ -429,7 +438,7 @@
|
|
|
429
438
|
scale: isNumber,
|
|
430
439
|
config: isObject,
|
|
431
440
|
format: (i) => typeof i === "string" &&
|
|
432
|
-
!!
|
|
441
|
+
!!RegExp(/^(XMLDocument|niconicome|formatted|legacy|legacyOwner|owner|v1|default|empty)$/).exec(i),
|
|
433
442
|
video: (i) => typeof i === "object" && i.nodeName === "VIDEO",
|
|
434
443
|
};
|
|
435
444
|
for (const key of Object.keys(keys)) {
|
|
@@ -442,6 +451,20 @@
|
|
|
442
451
|
return true;
|
|
443
452
|
},
|
|
444
453
|
},
|
|
454
|
+
internal: {
|
|
455
|
+
CommentMeasuredContentItem: (i) => objectVerify(i, ["content", "slicedContent", "width"]),
|
|
456
|
+
CommentMeasuredContentItemArray: (i) => Array.isArray(i) &&
|
|
457
|
+
i.every(typeGuard.internal.CommentMeasuredContentItem),
|
|
458
|
+
MultiConfigItem: (i) => typeof i === "object" && objectVerify(i, ["html5", "flash"]),
|
|
459
|
+
HTML5Fonts: (i) => i === "defont" || i === "mincho" || i === "gothic",
|
|
460
|
+
MeasureInput: (i) => objectVerify(i, [
|
|
461
|
+
"font",
|
|
462
|
+
"content",
|
|
463
|
+
"lineHeight",
|
|
464
|
+
"charSize",
|
|
465
|
+
"lineCount",
|
|
466
|
+
]),
|
|
467
|
+
},
|
|
445
468
|
};
|
|
446
469
|
const objectVerify = (item, keys) => {
|
|
447
470
|
if (typeof item !== "object" || !item)
|
|
@@ -468,13 +491,10 @@
|
|
|
468
491
|
});
|
|
469
492
|
|
|
470
493
|
const getConfig = (input, isFlash = false) => {
|
|
471
|
-
if (
|
|
472
|
-
Object.prototype.hasOwnProperty.call(input, "flash")) {
|
|
494
|
+
if (typeGuard.internal.MultiConfigItem(input)) {
|
|
473
495
|
return input[isFlash ? "flash" : "html5"];
|
|
474
496
|
}
|
|
475
|
-
|
|
476
|
-
return input;
|
|
477
|
-
}
|
|
497
|
+
return input;
|
|
478
498
|
};
|
|
479
499
|
|
|
480
500
|
const isLineBreakResize = (comment) => {
|
|
@@ -535,12 +555,12 @@
|
|
|
535
555
|
processNicoscript(comment, commands);
|
|
536
556
|
const defaultCommand = getDefaultCommand(comment.vpos);
|
|
537
557
|
applyNicoScriptReplace(comment, commands);
|
|
538
|
-
const size = commands.size
|
|
558
|
+
const size = commands.size ?? defaultCommand.size ?? "medium";
|
|
539
559
|
return {
|
|
540
560
|
size: size,
|
|
541
|
-
loc: commands.loc
|
|
542
|
-
color: commands.color
|
|
543
|
-
font: commands.font
|
|
561
|
+
loc: commands.loc ?? defaultCommand.loc ?? "naka",
|
|
562
|
+
color: commands.color ?? defaultCommand.color ?? "#FFFFFF",
|
|
563
|
+
font: commands.font ?? defaultCommand.font ?? "defont",
|
|
544
564
|
fontSize: getConfig(config.fontSize, isFlash)[size].default,
|
|
545
565
|
long: commands.long ? Math.floor(Number(commands.long) * 100) : 300,
|
|
546
566
|
flash: isFlash,
|
|
@@ -551,26 +571,27 @@
|
|
|
551
571
|
strokeColor: commands.strokeColor,
|
|
552
572
|
wakuColor: commands.wakuColor,
|
|
553
573
|
fillColor: commands.fillColor,
|
|
574
|
+
button: commands.button,
|
|
554
575
|
};
|
|
555
576
|
};
|
|
556
577
|
const parseBrackets = (input) => {
|
|
557
578
|
const content = input.split(""), result = [];
|
|
558
579
|
let quote = "", last_i = "", string = "";
|
|
559
580
|
for (const i of content) {
|
|
560
|
-
if (
|
|
581
|
+
if (RegExp(/^["'\u300c]$/).exec(i) && quote === "") {
|
|
561
582
|
quote = i;
|
|
562
583
|
}
|
|
563
|
-
else if (
|
|
584
|
+
else if (RegExp(/^["']$/).exec(i) && quote === i && last_i !== "\\") {
|
|
564
585
|
result.push(string.replaceAll("\\n", "\n"));
|
|
565
586
|
quote = "";
|
|
566
587
|
string = "";
|
|
567
588
|
}
|
|
568
|
-
else if (i
|
|
589
|
+
else if (i === "\u300d" && quote === "\u300c") {
|
|
569
590
|
result.push(string);
|
|
570
591
|
quote = "";
|
|
571
592
|
string = "";
|
|
572
593
|
}
|
|
573
|
-
else if (quote === "" &&
|
|
594
|
+
else if (quote === "" && RegExp(/^\s+$/).exec(i)) {
|
|
574
595
|
if (string) {
|
|
575
596
|
result.push(string);
|
|
576
597
|
string = "";
|
|
@@ -598,10 +619,10 @@
|
|
|
598
619
|
start: comment.vpos,
|
|
599
620
|
long: commands.long === undefined ? undefined : Math.floor(commands.long * 100),
|
|
600
621
|
keyword: result[0],
|
|
601
|
-
replace: result[1]
|
|
602
|
-
range: result[2]
|
|
603
|
-
target: result[3]
|
|
604
|
-
condition: result[4]
|
|
622
|
+
replace: result[1] ?? "",
|
|
623
|
+
range: result[2] ?? "\u5358",
|
|
624
|
+
target: result[3] ?? "\u30b3\u30e1",
|
|
625
|
+
condition: result[4] ?? "\u90e8\u5206\u4e00\u81f4",
|
|
605
626
|
color: commands.color,
|
|
606
627
|
size: commands.size,
|
|
607
628
|
font: commands.font,
|
|
@@ -624,8 +645,14 @@
|
|
|
624
645
|
});
|
|
625
646
|
};
|
|
626
647
|
const processNicoscript = (comment, commands) => {
|
|
627
|
-
const nicoscript =
|
|
628
|
-
if (!nicoscript
|
|
648
|
+
const nicoscript = RegExp(/^[@\uff20](\u30c7\u30d5\u30a9\u30eb\u30c8|\u7f6e\u63db|\u9006|\u30b3\u30e1\u30f3\u30c8\u7981\u6b62|\u30b7\u30fc\u30af\u7981\u6b62|\u30b8\u30e3\u30f3\u30d7|\u30dc\u30bf\u30f3)(?:\s(.+))?/).exec(comment.content);
|
|
649
|
+
if (!nicoscript)
|
|
650
|
+
return;
|
|
651
|
+
if (nicoscript[1] === "\u30dc\u30bf\u30f3" && nicoscript[2]) {
|
|
652
|
+
processAtButton(comment, commands);
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
if (!comment.owner)
|
|
629
656
|
return;
|
|
630
657
|
commands.invisible = true;
|
|
631
658
|
if (nicoscript[1] === "\u30c7\u30d5\u30a9\u30eb\u30c8") {
|
|
@@ -663,8 +690,8 @@
|
|
|
663
690
|
});
|
|
664
691
|
};
|
|
665
692
|
const processReverseScript = (comment, commands) => {
|
|
666
|
-
const reverse =
|
|
667
|
-
if (!reverse
|
|
693
|
+
const reverse = RegExp(/^[@\uff20]\u9006(?:\s+)?(\u5168|\u30b3\u30e1|\u6295\u30b3\u30e1)?/).exec(comment.content);
|
|
694
|
+
if (!reverse?.[1] || !typeGuard.nicoScript.range.target(reverse[1]))
|
|
668
695
|
return;
|
|
669
696
|
if (commands.long === undefined) {
|
|
670
697
|
commands.long = 30;
|
|
@@ -694,8 +721,8 @@
|
|
|
694
721
|
});
|
|
695
722
|
};
|
|
696
723
|
const processJumpScript$1 = (comment, commands, input) => {
|
|
697
|
-
const options =
|
|
698
|
-
if (!options
|
|
724
|
+
const options = RegExp(/\s*((?:sm|so|nm|\uff53\uff4d|\uff53\uff4f|\uff4e\uff4d)?[1-9\uff11-\uff19][0-9\uff11-\uff19]*|#[0-9]+:[0-9]+(?:\.[0-9]+)?)\s+(.*)/).exec(input);
|
|
725
|
+
if (!options?.[1])
|
|
699
726
|
return;
|
|
700
727
|
nicoScripts.jump.unshift({
|
|
701
728
|
start: comment.vpos,
|
|
@@ -704,6 +731,27 @@
|
|
|
704
731
|
message: options[2],
|
|
705
732
|
});
|
|
706
733
|
};
|
|
734
|
+
const processAtButton = (comment, commands) => {
|
|
735
|
+
const args = parseBrackets(comment.content);
|
|
736
|
+
if (args[1] === undefined)
|
|
737
|
+
return;
|
|
738
|
+
commands.invisible = false;
|
|
739
|
+
const content = RegExp(/^(?:(?<before>.*?)\[)?(?<body>.*?)(?:\](?<after>[^\]]*?))?$/su).exec(args[1]);
|
|
740
|
+
const message = {
|
|
741
|
+
before: content.groups?.before ?? "",
|
|
742
|
+
body: content.groups?.body ?? "",
|
|
743
|
+
after: content.groups?.after ?? "",
|
|
744
|
+
};
|
|
745
|
+
commands.button = {
|
|
746
|
+
message,
|
|
747
|
+
commentMessage: args[2] ?? `${message.before}${message.body}${message.after}`,
|
|
748
|
+
commentVisible: args[3] !== "\u975e\u8868\u793a",
|
|
749
|
+
commentMail: args[4]?.split(",") ?? [],
|
|
750
|
+
limit: Number(args[5] ?? 1),
|
|
751
|
+
local: comment.mail.includes("local"),
|
|
752
|
+
hidden: comment.mail.includes("hidden"),
|
|
753
|
+
};
|
|
754
|
+
};
|
|
707
755
|
const parseCommands = (comment) => {
|
|
708
756
|
const commands = comment.mail, isFlash = isFlashComment(comment);
|
|
709
757
|
const result = {
|
|
@@ -730,22 +778,22 @@
|
|
|
730
778
|
};
|
|
731
779
|
const parseCommand = (comment, _command, result, isFlash) => {
|
|
732
780
|
const command = _command.toLowerCase();
|
|
733
|
-
const long =
|
|
781
|
+
const long = RegExp(/^[@\uff20]([0-9.]+)/).exec(command);
|
|
734
782
|
if (long) {
|
|
735
783
|
result.long = Number(long[1]);
|
|
736
784
|
return;
|
|
737
785
|
}
|
|
738
|
-
const strokeColor = getColor(
|
|
786
|
+
const strokeColor = getColor(RegExp(/^nico:stroke:(.+)$/).exec(command));
|
|
739
787
|
if (strokeColor) {
|
|
740
788
|
result.strokeColor ??= strokeColor;
|
|
741
789
|
return;
|
|
742
790
|
}
|
|
743
|
-
const rectColor = getColor(
|
|
791
|
+
const rectColor = getColor(RegExp(/^nico:waku:(.+)$/).exec(command));
|
|
744
792
|
if (rectColor) {
|
|
745
793
|
result.wakuColor ??= rectColor;
|
|
746
794
|
return;
|
|
747
795
|
}
|
|
748
|
-
const fillColor = getColor(
|
|
796
|
+
const fillColor = getColor(RegExp(/^nico:fill:(.+)$/).exec(command));
|
|
749
797
|
if (fillColor) {
|
|
750
798
|
result.fillColor ??= fillColor;
|
|
751
799
|
return;
|
|
@@ -763,7 +811,7 @@
|
|
|
763
811
|
result.color ??= config.colors[command];
|
|
764
812
|
return;
|
|
765
813
|
}
|
|
766
|
-
const colorCode =
|
|
814
|
+
const colorCode = RegExp(/^#(?:[0-9a-z]{3}|[0-9a-z]{6})$/).exec(command);
|
|
767
815
|
if (colorCode && comment.premium) {
|
|
768
816
|
result.color ??= colorCode[0].toUpperCase();
|
|
769
817
|
return;
|
|
@@ -948,7 +996,7 @@
|
|
|
948
996
|
const changeCALayer = (rawData) => {
|
|
949
997
|
const userScoreList = getUsersScore(rawData);
|
|
950
998
|
const filteredComments = removeDuplicateCommentArt(rawData);
|
|
951
|
-
const commentArts = filteredComments.filter((comment) => (userScoreList[comment.user_id]
|
|
999
|
+
const commentArts = filteredComments.filter((comment) => (userScoreList[comment.user_id] ?? 0) >= config.sameCAMinScore &&
|
|
952
1000
|
!comment.owner);
|
|
953
1001
|
const commentArtsGroupedByUser = groupCommentsByUser(commentArts);
|
|
954
1002
|
const commentArtsGroupedByTimes = groupCommentsByTime(commentArtsGroupedByUser);
|
|
@@ -967,7 +1015,7 @@
|
|
|
967
1015
|
comment.mail.includes("full")) {
|
|
968
1016
|
userScoreList[comment.user_id] += 5;
|
|
969
1017
|
}
|
|
970
|
-
const lineCount = (comment.content.match(/\r\n|\n|\r/g)
|
|
1018
|
+
const lineCount = (comment.content.match(/\r\n|\n|\r/g) ?? []).length;
|
|
971
1019
|
if (lineCount > 2) {
|
|
972
1020
|
userScoreList[comment.user_id] += lineCount / 2;
|
|
973
1021
|
}
|
|
@@ -979,7 +1027,7 @@
|
|
|
979
1027
|
return comments.filter((comment) => {
|
|
980
1028
|
const key = `${comment.content}@@${[...comment.mail]
|
|
981
1029
|
.sort()
|
|
982
|
-
.filter((e) => !
|
|
1030
|
+
.filter((e) => !RegExp(/@[\d.]+|184|device:.+|patissier|ca/).exec(e))
|
|
983
1031
|
.join("")}`, lastComment = index[key];
|
|
984
1032
|
if (lastComment === undefined) {
|
|
985
1033
|
index[key] = comment;
|
|
@@ -1091,7 +1139,7 @@
|
|
|
1091
1139
|
return index;
|
|
1092
1140
|
};
|
|
1093
1141
|
const getFlashFontName = (font) => {
|
|
1094
|
-
if (font
|
|
1142
|
+
if (font === "simsunStrong" || font === "simsunWeak")
|
|
1095
1143
|
return "simsun";
|
|
1096
1144
|
if (font === "gothic")
|
|
1097
1145
|
return "defont";
|
|
@@ -1099,11 +1147,11 @@
|
|
|
1099
1147
|
};
|
|
1100
1148
|
const parseContent = (content) => {
|
|
1101
1149
|
const results = [];
|
|
1102
|
-
const lines = (content.match(/\n|[^\n]+/g)
|
|
1150
|
+
const lines = Array.from(content.match(/\n|[^\n]+/g) ?? []);
|
|
1103
1151
|
for (const line of lines) {
|
|
1104
1152
|
const lineContent = parseLine(line);
|
|
1105
1153
|
const firstContent = lineContent[0];
|
|
1106
|
-
if (firstContent
|
|
1154
|
+
if (firstContent?.font) {
|
|
1107
1155
|
results.push(...lineContent.map((val) => {
|
|
1108
1156
|
if (!val.font) {
|
|
1109
1157
|
val.font = firstContent.font;
|
|
@@ -1118,8 +1166,9 @@
|
|
|
1118
1166
|
return results;
|
|
1119
1167
|
};
|
|
1120
1168
|
const parseLine = (line) => {
|
|
1169
|
+
const parts = Array.from(line.match(/[ -~。-゚]+|[^ -~。-゚]+/g) ?? []);
|
|
1121
1170
|
const lineContent = [];
|
|
1122
|
-
for (const part of
|
|
1171
|
+
for (const part of parts) {
|
|
1123
1172
|
if (part.match(/[ -~。-゚]+/g) !== null) {
|
|
1124
1173
|
lineContent.push({ content: part, slicedContent: part.split("\n") });
|
|
1125
1174
|
continue;
|
|
@@ -1200,6 +1249,115 @@
|
|
|
1200
1249
|
font: getFlashFontName(secondVal.font),
|
|
1201
1250
|
});
|
|
1202
1251
|
};
|
|
1252
|
+
const getButtonParts = (comment) => {
|
|
1253
|
+
let leftParts = undefined;
|
|
1254
|
+
const parts = [];
|
|
1255
|
+
const atButtonPadding = getConfig(config.atButtonPadding, true);
|
|
1256
|
+
const lineOffset = comment.lineOffset;
|
|
1257
|
+
const lineHeight = comment.fontSize * comment.lineHeight;
|
|
1258
|
+
const offsetKey = comment.resizedY ? "resized" : "default";
|
|
1259
|
+
const offsetY = config.commentYPaddingTop[offsetKey] +
|
|
1260
|
+
comment.fontSize *
|
|
1261
|
+
comment.lineHeight *
|
|
1262
|
+
config.commentYOffset[comment.size][offsetKey];
|
|
1263
|
+
let leftOffset = 0, lineCount = 0, isLastButton = false;
|
|
1264
|
+
for (const item of comment.content) {
|
|
1265
|
+
const lines = item.slicedContent;
|
|
1266
|
+
for (let j = 0, n = lines.length; j < n; j++) {
|
|
1267
|
+
const line = lines[j];
|
|
1268
|
+
if (line === undefined)
|
|
1269
|
+
continue;
|
|
1270
|
+
const posY = (lineOffset + lineCount + 1) * lineHeight + offsetY;
|
|
1271
|
+
const partWidth = item.width[j] ?? 0;
|
|
1272
|
+
if (comment.button && !comment.button.hidden) {
|
|
1273
|
+
if (!isLastButton && item.isButton) {
|
|
1274
|
+
leftParts = {
|
|
1275
|
+
type: "left",
|
|
1276
|
+
left: leftOffset + atButtonPadding,
|
|
1277
|
+
top: posY - lineHeight + atButtonPadding,
|
|
1278
|
+
width: partWidth + atButtonPadding,
|
|
1279
|
+
height: lineHeight,
|
|
1280
|
+
};
|
|
1281
|
+
leftOffset += atButtonPadding * 2;
|
|
1282
|
+
}
|
|
1283
|
+
else if (isLastButton && item.isButton) {
|
|
1284
|
+
parts.push({
|
|
1285
|
+
type: "middle",
|
|
1286
|
+
left: leftOffset,
|
|
1287
|
+
top: posY - lineHeight + atButtonPadding,
|
|
1288
|
+
width: partWidth,
|
|
1289
|
+
height: lineHeight,
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
else if (isLastButton && !item.isButton) {
|
|
1293
|
+
if (leftParts) {
|
|
1294
|
+
comment.buttonObjects = {
|
|
1295
|
+
left: leftParts,
|
|
1296
|
+
middle: parts,
|
|
1297
|
+
right: {
|
|
1298
|
+
type: "right",
|
|
1299
|
+
right: leftOffset + atButtonPadding,
|
|
1300
|
+
top: posY - lineHeight + atButtonPadding,
|
|
1301
|
+
height: lineHeight,
|
|
1302
|
+
},
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
return comment;
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
if (j < n - 1) {
|
|
1309
|
+
leftOffset = 0;
|
|
1310
|
+
lineCount += 1;
|
|
1311
|
+
continue;
|
|
1312
|
+
}
|
|
1313
|
+
leftOffset += partWidth;
|
|
1314
|
+
}
|
|
1315
|
+
isLastButton = !!item.isButton;
|
|
1316
|
+
}
|
|
1317
|
+
if (comment.button && !comment.button.hidden && isLastButton && leftParts) {
|
|
1318
|
+
const posY = (lineOffset + lineCount + 1) * lineHeight + offsetY;
|
|
1319
|
+
comment.buttonObjects = {
|
|
1320
|
+
left: leftParts,
|
|
1321
|
+
middle: parts,
|
|
1322
|
+
right: {
|
|
1323
|
+
type: "right",
|
|
1324
|
+
right: leftOffset + atButtonPadding,
|
|
1325
|
+
top: posY - lineHeight + atButtonPadding,
|
|
1326
|
+
height: lineHeight,
|
|
1327
|
+
},
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
return comment;
|
|
1331
|
+
};
|
|
1332
|
+
const buildAtButtonComment = (comment, vpos) => {
|
|
1333
|
+
if (!comment.button || comment.button.limit <= 0)
|
|
1334
|
+
return;
|
|
1335
|
+
comment.button.limit -= 1;
|
|
1336
|
+
const mail = [...comment.button.commentMail];
|
|
1337
|
+
if (!comment.button.commentVisible) {
|
|
1338
|
+
mail.push("invisible");
|
|
1339
|
+
}
|
|
1340
|
+
return {
|
|
1341
|
+
id: -1,
|
|
1342
|
+
vpos,
|
|
1343
|
+
content: comment.button.commentMessage,
|
|
1344
|
+
date: -1,
|
|
1345
|
+
date_usec: -1,
|
|
1346
|
+
owner: false,
|
|
1347
|
+
premium: true,
|
|
1348
|
+
mail,
|
|
1349
|
+
user_id: -10,
|
|
1350
|
+
layer: -1,
|
|
1351
|
+
is_my_post: true,
|
|
1352
|
+
};
|
|
1353
|
+
};
|
|
1354
|
+
|
|
1355
|
+
class TypeGuardError extends Error {
|
|
1356
|
+
constructor(options = {}) {
|
|
1357
|
+
super("Type Guard Error\nAn error occurred due to unexpected values\nPlease contact the developer on GitHub", options);
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
TypeGuardError.prototype.name = "TypeGuardError";
|
|
1203
1361
|
|
|
1204
1362
|
const getLineHeight = (fontSize, isFlash, resized = false) => {
|
|
1205
1363
|
const lineCounts = getConfig(config.lineCounts, isFlash), CommentStageSize = getConfig(config.CommentStageSize, isFlash), lineHeight = CommentStageSize.height / lineCounts.doubleResized[fontSize], defaultLineCount = lineCounts.default[fontSize];
|
|
@@ -1228,10 +1386,13 @@
|
|
|
1228
1386
|
let currentWidth = 0;
|
|
1229
1387
|
for (const item of comment.content) {
|
|
1230
1388
|
const lines = item.content.split("\n");
|
|
1231
|
-
context.font = parseFont(item.font
|
|
1389
|
+
context.font = parseFont(item.font ?? comment.font, fontSize);
|
|
1232
1390
|
const width = [];
|
|
1233
1391
|
for (let j = 0, n = lines.length; j < n; j++) {
|
|
1234
|
-
const
|
|
1392
|
+
const line = lines[j];
|
|
1393
|
+
if (line === undefined)
|
|
1394
|
+
throw new TypeGuardError();
|
|
1395
|
+
const measure = context.measureText(line);
|
|
1235
1396
|
currentWidth += measure.width;
|
|
1236
1397
|
width.push(measure.width);
|
|
1237
1398
|
if (j < lines.length - 1) {
|
|
@@ -1268,7 +1429,9 @@
|
|
|
1268
1429
|
__proto__: null,
|
|
1269
1430
|
ArrayEqual: ArrayEqual,
|
|
1270
1431
|
ArrayPush: ArrayPush,
|
|
1432
|
+
buildAtButtonComment: buildAtButtonComment,
|
|
1271
1433
|
changeCALayer: changeCALayer,
|
|
1434
|
+
getButtonParts: getButtonParts,
|
|
1272
1435
|
getCharSize: getCharSize,
|
|
1273
1436
|
getConfig: getConfig,
|
|
1274
1437
|
getDefaultCommand: getDefaultCommand,
|
|
@@ -1311,12 +1474,15 @@
|
|
|
1311
1474
|
context;
|
|
1312
1475
|
cacheKey;
|
|
1313
1476
|
comment;
|
|
1477
|
+
pos;
|
|
1314
1478
|
posY;
|
|
1315
1479
|
pluginName = "BaseComment";
|
|
1316
1480
|
image;
|
|
1481
|
+
buttonImage;
|
|
1317
1482
|
constructor(comment, context) {
|
|
1318
1483
|
this.context = context;
|
|
1319
1484
|
this.posY = 0;
|
|
1485
|
+
this.pos = { x: 0, y: 0 };
|
|
1320
1486
|
comment.content = comment.content.replace(/\t/g, "\u2003\u2003");
|
|
1321
1487
|
this.comment = this.convertComment(comment);
|
|
1322
1488
|
this.cacheKey =
|
|
@@ -1380,7 +1546,7 @@
|
|
|
1380
1546
|
console.error("convertComment method is not implemented", comment);
|
|
1381
1547
|
throw new NotImplementedError(this.pluginName, "convertComment");
|
|
1382
1548
|
}
|
|
1383
|
-
draw(vpos, showCollision,
|
|
1549
|
+
draw(vpos, showCollision, cursor) {
|
|
1384
1550
|
if (isBanActive(vpos))
|
|
1385
1551
|
return;
|
|
1386
1552
|
const reverse = isReverseActive(vpos, this.comment.owner);
|
|
@@ -1388,13 +1554,17 @@
|
|
|
1388
1554
|
const posY = this.comment.loc === "shita"
|
|
1389
1555
|
? config.canvasHeight - this.posY - this.comment.height
|
|
1390
1556
|
: this.posY;
|
|
1557
|
+
this.pos = {
|
|
1558
|
+
x: posX,
|
|
1559
|
+
y: posY,
|
|
1560
|
+
};
|
|
1391
1561
|
this._drawBackgroundColor(posX, posY);
|
|
1392
|
-
this._draw(posX, posY);
|
|
1562
|
+
this._draw(posX, posY, cursor);
|
|
1393
1563
|
this._drawRectColor(posX, posY);
|
|
1394
1564
|
this._drawCollision(posX, posY, showCollision);
|
|
1395
|
-
this._drawDebugInfo(posX, posY
|
|
1565
|
+
this._drawDebugInfo(posX, posY);
|
|
1396
1566
|
}
|
|
1397
|
-
_draw(posX, posY) {
|
|
1567
|
+
_draw(posX, posY, cursor) {
|
|
1398
1568
|
if (this.image === undefined) {
|
|
1399
1569
|
this.image = this.getTextImage();
|
|
1400
1570
|
}
|
|
@@ -1406,6 +1576,10 @@
|
|
|
1406
1576
|
else {
|
|
1407
1577
|
this.context.globalAlpha = 1;
|
|
1408
1578
|
}
|
|
1579
|
+
if (this.comment.button && !this.comment.button.hidden) {
|
|
1580
|
+
const button = this.getButtonImage(posX, posY, cursor);
|
|
1581
|
+
button && drawImage(this.context, button, posX, posY);
|
|
1582
|
+
}
|
|
1409
1583
|
drawImage(this.context, this.image, posX, posY);
|
|
1410
1584
|
this.context.restore();
|
|
1411
1585
|
}
|
|
@@ -1426,8 +1600,8 @@
|
|
|
1426
1600
|
this.context.restore();
|
|
1427
1601
|
}
|
|
1428
1602
|
}
|
|
1429
|
-
_drawDebugInfo(posX, posY
|
|
1430
|
-
if (
|
|
1603
|
+
_drawDebugInfo(posX, posY) {
|
|
1604
|
+
if (isDebug) {
|
|
1431
1605
|
this.context.save();
|
|
1432
1606
|
const font = this.context.font;
|
|
1433
1607
|
const fillStyle = this.context.fillStyle;
|
|
@@ -1491,19 +1665,60 @@
|
|
|
1491
1665
|
context,
|
|
1492
1666
|
};
|
|
1493
1667
|
}
|
|
1668
|
+
getButtonImage(posX, posY, cursor) {
|
|
1669
|
+
console.error("getButtonImage method is not implemented", posX, posY, cursor);
|
|
1670
|
+
throw new NotImplementedError(this.pluginName, "getButtonImage");
|
|
1671
|
+
}
|
|
1672
|
+
isHovered(cursor, posX, posY) {
|
|
1673
|
+
console.error("isHovered method is not implemented", posX, posY, cursor);
|
|
1674
|
+
throw new NotImplementedError(this.pluginName, "getButtonImage");
|
|
1675
|
+
}
|
|
1494
1676
|
}
|
|
1495
1677
|
|
|
1678
|
+
const drawLeftBorder = (context, left, top, width, height, radius) => {
|
|
1679
|
+
context.save();
|
|
1680
|
+
context.beginPath();
|
|
1681
|
+
context.moveTo(left + width, top);
|
|
1682
|
+
context.lineTo(left + radius, top);
|
|
1683
|
+
context.quadraticCurveTo(left, top, left, top + radius);
|
|
1684
|
+
context.lineTo(left, top + height - radius);
|
|
1685
|
+
context.quadraticCurveTo(left, top + height, left + radius, top + height);
|
|
1686
|
+
context.lineTo(left + width, top + height);
|
|
1687
|
+
context.stroke();
|
|
1688
|
+
context.restore();
|
|
1689
|
+
};
|
|
1690
|
+
const drawMiddleBorder = (context, left, top, width, height) => {
|
|
1691
|
+
context.save();
|
|
1692
|
+
context.beginPath();
|
|
1693
|
+
context.moveTo(left + width, top);
|
|
1694
|
+
context.lineTo(left, top);
|
|
1695
|
+
context.moveTo(left + width, top + height);
|
|
1696
|
+
context.lineTo(left, top + height);
|
|
1697
|
+
context.stroke();
|
|
1698
|
+
context.restore();
|
|
1699
|
+
};
|
|
1700
|
+
const drawRightBorder = (context, right, top, height, radius) => {
|
|
1701
|
+
context.save();
|
|
1702
|
+
context.beginPath();
|
|
1703
|
+
context.moveTo(right - radius, top);
|
|
1704
|
+
context.quadraticCurveTo(right, top, right, top + radius);
|
|
1705
|
+
context.lineTo(right, top + height - radius);
|
|
1706
|
+
context.quadraticCurveTo(right, top + height, right - radius, top + height);
|
|
1707
|
+
context.stroke();
|
|
1708
|
+
context.restore();
|
|
1709
|
+
};
|
|
1710
|
+
|
|
1496
1711
|
class FlashComment extends BaseComment {
|
|
1497
1712
|
_globalScale;
|
|
1498
|
-
scale;
|
|
1499
|
-
scaleX;
|
|
1500
1713
|
pluginName = "FlashComment";
|
|
1714
|
+
buttonImage;
|
|
1715
|
+
buttonContext;
|
|
1501
1716
|
constructor(comment, context) {
|
|
1502
1717
|
super(comment, context);
|
|
1503
|
-
this.scale ??= 1;
|
|
1504
|
-
this.scaleX ??= 1;
|
|
1505
1718
|
this._globalScale ??= getConfig(config.commentScale, true);
|
|
1506
|
-
this.
|
|
1719
|
+
const button = this.createCanvas();
|
|
1720
|
+
this.buttonImage = button.image;
|
|
1721
|
+
this.buttonContext = button.context;
|
|
1507
1722
|
}
|
|
1508
1723
|
get content() {
|
|
1509
1724
|
return this.comment.rawContent;
|
|
@@ -1518,7 +1733,7 @@
|
|
|
1518
1733
|
lineOffset,
|
|
1519
1734
|
};
|
|
1520
1735
|
const val = content[0];
|
|
1521
|
-
if (val
|
|
1736
|
+
if (val?.font) {
|
|
1522
1737
|
comment.font = val.font;
|
|
1523
1738
|
}
|
|
1524
1739
|
this.comment = this.getCommentSize(comment);
|
|
@@ -1529,50 +1744,57 @@
|
|
|
1529
1744
|
delete this.image;
|
|
1530
1745
|
}
|
|
1531
1746
|
convertComment(comment) {
|
|
1532
|
-
this.scale = 1;
|
|
1533
|
-
this.scaleX = 1;
|
|
1534
1747
|
this._globalScale = getConfig(config.commentScale, true);
|
|
1535
|
-
this.
|
|
1536
|
-
return this.getCommentSize(this.parseCommandAndNicoscript(comment));
|
|
1748
|
+
return getButtonParts(this.getCommentSize(this.parseCommandAndNicoscript(comment)));
|
|
1537
1749
|
}
|
|
1538
1750
|
getCommentSize(parsedData) {
|
|
1539
|
-
this.context.save();
|
|
1540
|
-
this.context.font = parseFont(parsedData.font, parsedData.fontSize);
|
|
1541
|
-
const size = parsedData;
|
|
1542
1751
|
if (parsedData.invisible) {
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1752
|
+
return {
|
|
1753
|
+
...parsedData,
|
|
1754
|
+
height: 0,
|
|
1755
|
+
width: 0,
|
|
1756
|
+
lineHeight: 0,
|
|
1757
|
+
fontSize: 0,
|
|
1758
|
+
resized: false,
|
|
1759
|
+
resizedX: false,
|
|
1760
|
+
resizedY: false,
|
|
1761
|
+
charSize: 0,
|
|
1762
|
+
scale: 1,
|
|
1763
|
+
scaleX: 1,
|
|
1764
|
+
content: [],
|
|
1765
|
+
};
|
|
1553
1766
|
}
|
|
1554
|
-
|
|
1555
|
-
|
|
1767
|
+
this.context.save();
|
|
1768
|
+
this.context.font = parseFont(parsedData.font, parsedData.fontSize);
|
|
1769
|
+
const measure = this.measureText({ ...parsedData, scale: 1 });
|
|
1770
|
+
if (options.scale !== 1 && parsedData.layer === -1) {
|
|
1556
1771
|
measure.height *= options.scale;
|
|
1557
1772
|
measure.width *= options.scale;
|
|
1558
1773
|
}
|
|
1559
|
-
size.height = measure.height * this._globalScale;
|
|
1560
|
-
size.width = measure.width * this._globalScale;
|
|
1561
|
-
size.lineHeight = measure.lineHeight;
|
|
1562
|
-
size.fontSize = measure.fontSize;
|
|
1563
|
-
size.content = measure.content;
|
|
1564
|
-
size.resized = measure.resized;
|
|
1565
|
-
size.resizedX = measure.resizedX;
|
|
1566
|
-
size.resizedY = measure.resizedY;
|
|
1567
|
-
size.charSize = measure.charSize;
|
|
1568
1774
|
this.context.restore();
|
|
1569
|
-
|
|
1775
|
+
if (parsedData.button && !parsedData.button.hidden) {
|
|
1776
|
+
measure.width += getConfig(config.atButtonPadding, true) * 4;
|
|
1777
|
+
}
|
|
1778
|
+
return {
|
|
1779
|
+
...parsedData,
|
|
1780
|
+
height: measure.height * this._globalScale,
|
|
1781
|
+
width: measure.width * this._globalScale,
|
|
1782
|
+
lineHeight: measure.lineHeight,
|
|
1783
|
+
fontSize: measure.fontSize,
|
|
1784
|
+
resized: measure.resized,
|
|
1785
|
+
resizedX: measure.resizedX,
|
|
1786
|
+
resizedY: measure.resizedY,
|
|
1787
|
+
charSize: measure.charSize,
|
|
1788
|
+
scale: measure.scale,
|
|
1789
|
+
scaleX: measure.scaleX,
|
|
1790
|
+
content: measure.content,
|
|
1791
|
+
};
|
|
1570
1792
|
}
|
|
1571
1793
|
parseCommandAndNicoscript(comment) {
|
|
1572
1794
|
const data = parseCommandAndNicoScript(comment);
|
|
1573
|
-
const { content, lineCount, lineOffset } = this.parseContent(comment.content);
|
|
1795
|
+
const { content, lineCount, lineOffset } = this.parseContent(comment.content, data.button);
|
|
1574
1796
|
const val = content[0];
|
|
1575
|
-
if (val
|
|
1797
|
+
if (val?.font) {
|
|
1576
1798
|
data.font = val.font;
|
|
1577
1799
|
}
|
|
1578
1800
|
return {
|
|
@@ -1584,16 +1806,23 @@
|
|
|
1584
1806
|
lineOffset,
|
|
1585
1807
|
};
|
|
1586
1808
|
}
|
|
1587
|
-
parseContent(input) {
|
|
1588
|
-
const content =
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1809
|
+
parseContent(input, button) {
|
|
1810
|
+
const content = button
|
|
1811
|
+
? [
|
|
1812
|
+
...parseContent(button.message.before),
|
|
1813
|
+
...parseContent(button.message.body).map((val) => {
|
|
1814
|
+
val.isButton = true;
|
|
1815
|
+
return val;
|
|
1816
|
+
}),
|
|
1817
|
+
...parseContent(button.message.after),
|
|
1818
|
+
]
|
|
1819
|
+
: parseContent(input);
|
|
1820
|
+
const lineCount = (input.match(/\n/g)?.length ?? 0) + 1;
|
|
1821
|
+
const lineOffset = (input.match(new RegExp(config.FlashScriptChar.super, "g"))?.length ??
|
|
1593
1822
|
0) *
|
|
1594
1823
|
-1 *
|
|
1595
1824
|
config.scriptCharOffset +
|
|
1596
|
-
(input.match(new RegExp(config.FlashScriptChar.sub, "g"))?.length
|
|
1825
|
+
(input.match(new RegExp(config.FlashScriptChar.sub, "g"))?.length ?? 0) *
|
|
1597
1826
|
config.scriptCharOffset;
|
|
1598
1827
|
return {
|
|
1599
1828
|
content,
|
|
@@ -1615,32 +1844,34 @@
|
|
|
1615
1844
|
const { width_arr, spacedWidth_arr } = this._measureContent(comment);
|
|
1616
1845
|
const leadLine = (function () {
|
|
1617
1846
|
let max = 0, index = -1;
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
if (val && max < val) {
|
|
1847
|
+
spacedWidth_arr.forEach((val, i) => {
|
|
1848
|
+
if (max < val) {
|
|
1621
1849
|
max = val;
|
|
1622
1850
|
index = i;
|
|
1623
1851
|
}
|
|
1624
|
-
}
|
|
1852
|
+
});
|
|
1625
1853
|
return { max, index };
|
|
1626
1854
|
})();
|
|
1627
1855
|
const width = leadLine.max;
|
|
1628
|
-
|
|
1629
|
-
const width_max = width *
|
|
1856
|
+
const scaleX = leadLine.max / (width_arr[leadLine.index] ?? 1);
|
|
1857
|
+
const width_max = width * comment.scale;
|
|
1630
1858
|
const height = (comment.fontSize * comment.lineHeight * lineCount +
|
|
1631
1859
|
config.commentYPaddingTop[comment.resizedY ? "resized" : "default"]) *
|
|
1632
|
-
|
|
1860
|
+
comment.scale;
|
|
1633
1861
|
if (comment.loc !== "naka") {
|
|
1634
1862
|
const widthLimit = getConfig(config.CommentStageSize, true)[comment.full ? "fullWidth" : "width"];
|
|
1635
1863
|
if (width_max > widthLimit && !comment.resizedX) {
|
|
1636
1864
|
comment.fontSize = configFontSize[comment.size].default;
|
|
1637
1865
|
comment.lineHeight = configLineHeight[comment.size].default;
|
|
1638
|
-
|
|
1866
|
+
comment.scale = widthLimit / width_max;
|
|
1639
1867
|
comment.resizedX = true;
|
|
1640
1868
|
comment.resized = true;
|
|
1641
1869
|
return this.measureText(comment);
|
|
1642
1870
|
}
|
|
1643
1871
|
}
|
|
1872
|
+
if (!typeGuard.internal.CommentMeasuredContentItemArray(comment.content)) {
|
|
1873
|
+
throw new TypeGuardError();
|
|
1874
|
+
}
|
|
1644
1875
|
return {
|
|
1645
1876
|
width: width_max,
|
|
1646
1877
|
charSize: 0,
|
|
@@ -1651,6 +1882,8 @@
|
|
|
1651
1882
|
content: comment.content,
|
|
1652
1883
|
resizedX: !!comment.resizedX,
|
|
1653
1884
|
resizedY: !!comment.resizedY,
|
|
1885
|
+
scale: comment.scale,
|
|
1886
|
+
scaleX,
|
|
1654
1887
|
};
|
|
1655
1888
|
}
|
|
1656
1889
|
_measureContent(comment) {
|
|
@@ -1659,7 +1892,7 @@
|
|
|
1659
1892
|
for (const item of comment.content) {
|
|
1660
1893
|
const lines = item.content.split("\n");
|
|
1661
1894
|
const widths = [];
|
|
1662
|
-
this.context.font = parseFont(item.font
|
|
1895
|
+
this.context.font = parseFont(item.font ?? comment.font, comment.fontSize);
|
|
1663
1896
|
for (let i = 0, n = lines.length; i < n; i++) {
|
|
1664
1897
|
const value = lines[i];
|
|
1665
1898
|
if (value === undefined)
|
|
@@ -1690,13 +1923,13 @@
|
|
|
1690
1923
|
for (let i = 0, n = this.comment.lineCount; i < n; i++) {
|
|
1691
1924
|
const linePosY = ((i + 1) * (this.comment.fontSize * this.comment.lineHeight) +
|
|
1692
1925
|
config.commentYPaddingTop[this.comment.resizedY ? "resized" : "default"]) *
|
|
1693
|
-
this.scale;
|
|
1926
|
+
this.comment.scale;
|
|
1694
1927
|
this.context.strokeStyle = `rgba(255,255,0,0.25)`;
|
|
1695
1928
|
this.context.strokeRect(posX, posY + linePosY * this._globalScale, this.comment.width, this.comment.fontSize *
|
|
1696
1929
|
this.comment.lineHeight *
|
|
1697
1930
|
-1 *
|
|
1698
1931
|
this._globalScale *
|
|
1699
|
-
this.scale *
|
|
1932
|
+
this.comment.scale *
|
|
1700
1933
|
(this.comment.layer === -1 ? options.scale : 1));
|
|
1701
1934
|
}
|
|
1702
1935
|
this.context.restore();
|
|
@@ -1704,27 +1937,19 @@
|
|
|
1704
1937
|
}
|
|
1705
1938
|
_generateTextImage() {
|
|
1706
1939
|
const { image, context } = this.createCanvas();
|
|
1707
|
-
image
|
|
1708
|
-
|
|
1709
|
-
context.strokeStyle = getStrokeColor(this.comment);
|
|
1710
|
-
context.fillStyle = this.comment.color;
|
|
1711
|
-
context.textAlign = "start";
|
|
1712
|
-
context.textBaseline = "alphabetic";
|
|
1713
|
-
context.lineWidth = 4;
|
|
1714
|
-
context.font = parseFont(this.comment.font, this.comment.fontSize);
|
|
1715
|
-
const scale = this._globalScale *
|
|
1716
|
-
this.scale *
|
|
1717
|
-
(this.comment.layer === -1 ? options.scale : 1);
|
|
1718
|
-
context.scale(scale * this.scaleX, scale);
|
|
1940
|
+
this._setupCanvas(image, context);
|
|
1941
|
+
const atButtonPadding = getConfig(config.atButtonPadding, true);
|
|
1719
1942
|
const lineOffset = this.comment.lineOffset;
|
|
1943
|
+
const lineHeight = this.comment.fontSize * this.comment.lineHeight;
|
|
1720
1944
|
const offsetKey = this.comment.resizedY ? "resized" : "default";
|
|
1721
1945
|
const offsetY = config.commentYPaddingTop[offsetKey] +
|
|
1722
1946
|
this.comment.fontSize *
|
|
1723
1947
|
this.comment.lineHeight *
|
|
1724
1948
|
config.commentYOffset[this.comment.size][offsetKey];
|
|
1725
|
-
let lastFont = this.comment.font, leftOffset = 0, lineCount = 0;
|
|
1949
|
+
let lastFont = this.comment.font, leftOffset = 0, lineCount = 0, isLastButton = false;
|
|
1950
|
+
console.log(this.comment);
|
|
1726
1951
|
for (const item of this.comment.content) {
|
|
1727
|
-
const font = item.font
|
|
1952
|
+
const font = item.font ?? this.comment.font;
|
|
1728
1953
|
if (lastFont !== font) {
|
|
1729
1954
|
lastFont = font;
|
|
1730
1955
|
context.font = parseFont(font, this.comment.fontSize);
|
|
@@ -1734,9 +1959,16 @@
|
|
|
1734
1959
|
const line = lines[j];
|
|
1735
1960
|
if (line === undefined)
|
|
1736
1961
|
continue;
|
|
1737
|
-
const posY = (lineOffset + lineCount + 1) *
|
|
1738
|
-
|
|
1739
|
-
|
|
1962
|
+
const posY = (lineOffset + lineCount + 1) * lineHeight + offsetY;
|
|
1963
|
+
const partWidth = item.width[j] ?? 0;
|
|
1964
|
+
if (this.comment.button && !this.comment.button.hidden) {
|
|
1965
|
+
if (!isLastButton && item.isButton) {
|
|
1966
|
+
leftOffset += atButtonPadding * 2;
|
|
1967
|
+
}
|
|
1968
|
+
else if (isLastButton && !item.isButton) {
|
|
1969
|
+
leftOffset += atButtonPadding * 2;
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1740
1972
|
context.strokeText(line, leftOffset, posY);
|
|
1741
1973
|
context.fillText(line, leftOffset, posY);
|
|
1742
1974
|
if (j < n - 1) {
|
|
@@ -1744,11 +1976,79 @@
|
|
|
1744
1976
|
lineCount += 1;
|
|
1745
1977
|
continue;
|
|
1746
1978
|
}
|
|
1747
|
-
leftOffset +=
|
|
1979
|
+
leftOffset += partWidth;
|
|
1748
1980
|
}
|
|
1981
|
+
isLastButton = !!item.isButton;
|
|
1749
1982
|
}
|
|
1750
1983
|
return image;
|
|
1751
1984
|
}
|
|
1985
|
+
getButtonImage(posX, posY, cursor) {
|
|
1986
|
+
if (!this.comment.button || this.comment.button.hidden)
|
|
1987
|
+
return undefined;
|
|
1988
|
+
const { image, context } = this._setupCanvas(this.buttonImage, this.buttonContext);
|
|
1989
|
+
const parts = this.comment.buttonObjects;
|
|
1990
|
+
if (!parts)
|
|
1991
|
+
return undefined;
|
|
1992
|
+
const atButtonRadius = getConfig(config.atButtonRadius, true);
|
|
1993
|
+
const isHover = this.isHovered(cursor, posX, posY);
|
|
1994
|
+
context.save();
|
|
1995
|
+
context.strokeStyle = isHover ? this.comment.color : "white";
|
|
1996
|
+
drawLeftBorder(context, parts.left.left, parts.left.top, parts.left.width, parts.left.height, atButtonRadius);
|
|
1997
|
+
for (const part of parts.middle) {
|
|
1998
|
+
drawMiddleBorder(context, part.left, part.top, part.width, part.height);
|
|
1999
|
+
}
|
|
2000
|
+
drawRightBorder(context, parts.right.right, parts.right.top, parts.right.height, atButtonRadius);
|
|
2001
|
+
context.restore();
|
|
2002
|
+
return image;
|
|
2003
|
+
}
|
|
2004
|
+
isHovered(_cursor, _posX, _posY) {
|
|
2005
|
+
if (!_cursor || !this.comment.buttonObjects)
|
|
2006
|
+
return false;
|
|
2007
|
+
const { left, middle, right } = this.comment.buttonObjects;
|
|
2008
|
+
const scale = this._globalScale *
|
|
2009
|
+
this.comment.scale *
|
|
2010
|
+
(this.comment.layer === -1 ? options.scale : 1);
|
|
2011
|
+
const posX = (_posX ?? this.pos.x) / scale;
|
|
2012
|
+
const posY = (_posY ?? this.pos.y) / scale;
|
|
2013
|
+
const cursor = {
|
|
2014
|
+
x: _cursor.x / scale,
|
|
2015
|
+
y: _cursor.y / scale,
|
|
2016
|
+
};
|
|
2017
|
+
if (cursor.x < posX ||
|
|
2018
|
+
posX + this.comment.width < cursor.x ||
|
|
2019
|
+
cursor.y < posY + left.top ||
|
|
2020
|
+
posY + right.top + right.height < cursor.y) {
|
|
2021
|
+
return false;
|
|
2022
|
+
}
|
|
2023
|
+
const atButtonPadding = getConfig(config.atButtonPadding, true);
|
|
2024
|
+
const between = (val, min, max) => {
|
|
2025
|
+
return min < val && val < max;
|
|
2026
|
+
};
|
|
2027
|
+
for (const part of [left, ...middle]) {
|
|
2028
|
+
if (between(cursor.x, posX + part.left, posX + part.left + part.width) &&
|
|
2029
|
+
between(cursor.y, posY + part.top, posY + part.top + part.height)) {
|
|
2030
|
+
return true;
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
return (between(cursor.x, posX + right.right - atButtonPadding, posX + right.right + atButtonPadding * 2) && between(cursor.y, posY + right.top, posY + right.top + right.height));
|
|
2034
|
+
}
|
|
2035
|
+
_setupCanvas(image, context) {
|
|
2036
|
+
const atButtonPadding = getConfig(config.atButtonPadding, true);
|
|
2037
|
+
image.width = this.comment.width;
|
|
2038
|
+
image.height =
|
|
2039
|
+
this.comment.height + (this.comment.button ? atButtonPadding * 2 : 0);
|
|
2040
|
+
context.strokeStyle = getStrokeColor(this.comment);
|
|
2041
|
+
context.fillStyle = this.comment.color;
|
|
2042
|
+
context.textAlign = "start";
|
|
2043
|
+
context.textBaseline = "alphabetic";
|
|
2044
|
+
context.lineWidth = 4;
|
|
2045
|
+
context.font = parseFont(this.comment.font, this.comment.fontSize);
|
|
2046
|
+
const scale = this._globalScale *
|
|
2047
|
+
this.comment.scale *
|
|
2048
|
+
(this.comment.layer === -1 ? options.scale : 1);
|
|
2049
|
+
context.scale(scale * this.comment.scaleX, scale);
|
|
2050
|
+
return { image, context };
|
|
2051
|
+
}
|
|
1752
2052
|
}
|
|
1753
2053
|
|
|
1754
2054
|
class HTML5Comment extends BaseComment {
|
|
@@ -1780,38 +2080,46 @@
|
|
|
1780
2080
|
return this.getCommentSize(this.parseCommandAndNicoscript(comment));
|
|
1781
2081
|
}
|
|
1782
2082
|
getCommentSize(parsedData) {
|
|
1783
|
-
this.context.save();
|
|
1784
|
-
this.context.font = parseFont(parsedData.font, parsedData.fontSize);
|
|
1785
|
-
const size = parsedData;
|
|
1786
2083
|
if (parsedData.invisible) {
|
|
1787
|
-
size.height = 0;
|
|
1788
|
-
size.width = 0;
|
|
1789
|
-
size.lineHeight = 0;
|
|
1790
|
-
size.fontSize = 0;
|
|
1791
|
-
size.resized = false;
|
|
1792
|
-
size.resizedX = false;
|
|
1793
|
-
size.resizedY = false;
|
|
1794
|
-
size.charSize = 0;
|
|
1795
2084
|
this.context.restore();
|
|
1796
|
-
return
|
|
2085
|
+
return {
|
|
2086
|
+
...parsedData,
|
|
2087
|
+
height: 0,
|
|
2088
|
+
width: 0,
|
|
2089
|
+
lineHeight: 0,
|
|
2090
|
+
fontSize: 0,
|
|
2091
|
+
resized: false,
|
|
2092
|
+
resizedX: false,
|
|
2093
|
+
resizedY: false,
|
|
2094
|
+
charSize: 0,
|
|
2095
|
+
content: [],
|
|
2096
|
+
scaleX: 1,
|
|
2097
|
+
scale: 1,
|
|
2098
|
+
};
|
|
1797
2099
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
2100
|
+
this.context.save();
|
|
2101
|
+
this.context.font = parseFont(parsedData.font, parsedData.fontSize);
|
|
2102
|
+
const measure = this.measureText({ ...parsedData, scale: 1 });
|
|
2103
|
+
if (options.scale !== 1 && parsedData.layer === -1) {
|
|
1800
2104
|
measure.height *= options.scale;
|
|
1801
2105
|
measure.width *= options.scale;
|
|
1802
2106
|
measure.fontSize *= options.scale;
|
|
1803
2107
|
}
|
|
1804
|
-
size.height = measure.height;
|
|
1805
|
-
size.width = measure.width;
|
|
1806
|
-
size.lineHeight = measure.lineHeight;
|
|
1807
|
-
size.fontSize = measure.fontSize;
|
|
1808
|
-
size.content = measure.content;
|
|
1809
|
-
size.resized = measure.resized;
|
|
1810
|
-
size.resizedX = measure.resizedX;
|
|
1811
|
-
size.resizedY = measure.resizedY;
|
|
1812
|
-
size.charSize = measure.charSize;
|
|
1813
2108
|
this.context.restore();
|
|
1814
|
-
return
|
|
2109
|
+
return {
|
|
2110
|
+
...parsedData,
|
|
2111
|
+
height: measure.height,
|
|
2112
|
+
width: measure.width,
|
|
2113
|
+
lineHeight: measure.lineHeight,
|
|
2114
|
+
fontSize: measure.fontSize,
|
|
2115
|
+
resized: measure.resized,
|
|
2116
|
+
resizedX: measure.resizedX,
|
|
2117
|
+
resizedY: measure.resizedY,
|
|
2118
|
+
charSize: measure.charSize,
|
|
2119
|
+
content: measure.content,
|
|
2120
|
+
scaleX: measure.scaleX,
|
|
2121
|
+
scale: measure.scale,
|
|
2122
|
+
};
|
|
1815
2123
|
}
|
|
1816
2124
|
parseCommandAndNicoscript(comment) {
|
|
1817
2125
|
const data = parseCommandAndNicoScript(comment);
|
|
@@ -1832,7 +2140,7 @@
|
|
|
1832
2140
|
slicedContent: input.split("\n"),
|
|
1833
2141
|
});
|
|
1834
2142
|
const lineCount = content.reduce((pv, val) => {
|
|
1835
|
-
return pv + (val.content.match(/\n/g)?.length
|
|
2143
|
+
return pv + (val.content.match(/\n/g)?.length ?? 0);
|
|
1836
2144
|
}, 1);
|
|
1837
2145
|
const lineOffset = 0;
|
|
1838
2146
|
return {
|
|
@@ -1865,21 +2173,28 @@
|
|
|
1865
2173
|
continue;
|
|
1866
2174
|
item.width = itemWidth[i];
|
|
1867
2175
|
}
|
|
1868
|
-
comment.fontSize = (comment.charSize
|
|
2176
|
+
comment.fontSize = (comment.charSize ?? 0) * 0.8;
|
|
2177
|
+
if (!typeGuard.internal.CommentMeasuredContentItemArray(comment.content)) {
|
|
2178
|
+
throw new TypeGuardError();
|
|
2179
|
+
}
|
|
1869
2180
|
return {
|
|
1870
2181
|
width: width * scale,
|
|
1871
2182
|
height: height * scale,
|
|
1872
2183
|
resized: !!comment.resized,
|
|
1873
2184
|
fontSize: comment.fontSize,
|
|
1874
|
-
lineHeight: comment.lineHeight
|
|
2185
|
+
lineHeight: comment.lineHeight ?? 0,
|
|
1875
2186
|
content: comment.content,
|
|
1876
2187
|
resizedX: !!comment.resizedX,
|
|
1877
2188
|
resizedY: !!comment.resizedY,
|
|
1878
|
-
charSize: comment.charSize
|
|
2189
|
+
charSize: comment.charSize ?? 0,
|
|
2190
|
+
scaleX: 1,
|
|
2191
|
+
scale: 1,
|
|
1879
2192
|
};
|
|
1880
2193
|
}
|
|
1881
2194
|
_measureComment(comment) {
|
|
1882
2195
|
const widthLimit = getConfig(config.CommentStageSize, false)[comment.full ? "fullWidth" : "width"];
|
|
2196
|
+
if (!typeGuard.internal.MeasureInput(comment))
|
|
2197
|
+
throw new TypeGuardError();
|
|
1883
2198
|
const measureResult = measure(comment, this.context);
|
|
1884
2199
|
if (comment.loc !== "naka" && measureResult.width > widthLimit) {
|
|
1885
2200
|
return this._processResizeX(comment, measureResult.width);
|
|
@@ -1893,9 +2208,11 @@
|
|
|
1893
2208
|
const scale = widthLimit / width;
|
|
1894
2209
|
comment.resizedX = true;
|
|
1895
2210
|
let _comment = { ...comment };
|
|
1896
|
-
_comment.charSize = (_comment.charSize
|
|
1897
|
-
_comment.lineHeight = (_comment.lineHeight
|
|
2211
|
+
_comment.charSize = (_comment.charSize ?? 0) * scale;
|
|
2212
|
+
_comment.lineHeight = (_comment.lineHeight ?? 0) * scale;
|
|
1898
2213
|
_comment.fontSize = _comment.charSize * 0.8;
|
|
2214
|
+
if (!typeGuard.internal.MeasureInput(_comment))
|
|
2215
|
+
throw new TypeGuardError();
|
|
1899
2216
|
let result = measure(_comment, this.context);
|
|
1900
2217
|
if (result.width > widthLimit) {
|
|
1901
2218
|
while (result.width >= widthLimit) {
|
|
@@ -1919,7 +2236,7 @@
|
|
|
1919
2236
|
_comment = lastComment;
|
|
1920
2237
|
}
|
|
1921
2238
|
if (comment.resizedY) {
|
|
1922
|
-
const scale = (_comment.charSize
|
|
2239
|
+
const scale = (_comment.charSize ?? 0) / (comment.charSize ?? 0);
|
|
1923
2240
|
comment.charSize = scale * charSize;
|
|
1924
2241
|
comment.lineHeight = scale * lineHeight;
|
|
1925
2242
|
}
|
|
@@ -1927,7 +2244,9 @@
|
|
|
1927
2244
|
comment.charSize = _comment.charSize;
|
|
1928
2245
|
comment.lineHeight = _comment.lineHeight;
|
|
1929
2246
|
}
|
|
1930
|
-
comment.fontSize = (comment.charSize
|
|
2247
|
+
comment.fontSize = (comment.charSize ?? 0) * 0.8;
|
|
2248
|
+
if (!typeGuard.internal.MeasureInput(comment))
|
|
2249
|
+
throw new TypeGuardError();
|
|
1931
2250
|
return measure(comment, this.context);
|
|
1932
2251
|
}
|
|
1933
2252
|
_drawCollision(posX, posY, showCollision) {
|
|
@@ -1937,11 +2256,12 @@
|
|
|
1937
2256
|
this.context.strokeStyle = "rgba(0,255,255,1)";
|
|
1938
2257
|
this.context.strokeRect(posX, posY, this.comment.width, this.comment.height);
|
|
1939
2258
|
for (let i = 0, n = this.comment.lineCount; i < n; i++) {
|
|
2259
|
+
if (!typeGuard.internal.HTML5Fonts(this.comment.font))
|
|
2260
|
+
throw new TypeGuardError();
|
|
1940
2261
|
const linePosY = (this.comment.lineHeight * (i + 1) +
|
|
1941
2262
|
(this.comment.charSize - this.comment.lineHeight) / 2 +
|
|
1942
2263
|
this.comment.lineHeight * -0.16 +
|
|
1943
|
-
(config.fonts[this.comment.font]?.offset ||
|
|
1944
|
-
0)) *
|
|
2264
|
+
(config.fonts[this.comment.font]?.offset || 0)) *
|
|
1945
2265
|
scale;
|
|
1946
2266
|
this.context.strokeStyle = "rgba(255,255,0,0.5)";
|
|
1947
2267
|
this.context.strokeRect(posX, posY + linePosY, this.comment.width, this.comment.fontSize * -1 * scale);
|
|
@@ -1969,6 +2289,8 @@
|
|
|
1969
2289
|
(this.comment.layer === -1 ? options.scale : 1);
|
|
1970
2290
|
context.scale(drawScale, drawScale);
|
|
1971
2291
|
let lineCount = 0;
|
|
2292
|
+
if (!typeGuard.internal.HTML5Fonts(this.comment.font))
|
|
2293
|
+
throw new TypeGuardError();
|
|
1972
2294
|
const offsetY = (this.comment.charSize - this.comment.lineHeight) / 2 +
|
|
1973
2295
|
this.comment.lineHeight * -0.16 +
|
|
1974
2296
|
(config.fonts[this.comment.font]?.offset || 0);
|
|
@@ -1987,6 +2309,12 @@
|
|
|
1987
2309
|
}
|
|
1988
2310
|
return image;
|
|
1989
2311
|
}
|
|
2312
|
+
getButtonImage() {
|
|
2313
|
+
return undefined;
|
|
2314
|
+
}
|
|
2315
|
+
isHovered() {
|
|
2316
|
+
return false;
|
|
2317
|
+
}
|
|
1990
2318
|
}
|
|
1991
2319
|
|
|
1992
2320
|
var index = /*#__PURE__*/Object.freeze({
|
|
@@ -2142,17 +2470,17 @@
|
|
|
2142
2470
|
|
|
2143
2471
|
const initConfig = () => {
|
|
2144
2472
|
const platform = (function (ua) {
|
|
2145
|
-
if (
|
|
2473
|
+
if (RegExp(/windows nt 6\.[12]/i).exec(ua))
|
|
2146
2474
|
return "win7";
|
|
2147
|
-
else if (
|
|
2475
|
+
else if (RegExp(/windows nt (6\.3|10\.\d+)|win32/i).exec(ua))
|
|
2148
2476
|
return "win8_1";
|
|
2149
|
-
else if (
|
|
2477
|
+
else if (RegExp(/windows nt/i).exec(ua))
|
|
2150
2478
|
return "win";
|
|
2151
|
-
else if (
|
|
2479
|
+
else if (RegExp(/mac os x 10(.|_)(9|10)/i).exec(ua))
|
|
2152
2480
|
return "mac10_9";
|
|
2153
|
-
else if (
|
|
2481
|
+
else if (RegExp(/mac os x 10(.|_)\d{2}|darwin/i).exec(ua))
|
|
2154
2482
|
return "mac10_11";
|
|
2155
|
-
else if (
|
|
2483
|
+
else if (RegExp(/mac os x/i).exec(ua))
|
|
2156
2484
|
return "mac";
|
|
2157
2485
|
return "other";
|
|
2158
2486
|
})(typeof navigator !== "undefined" ? navigator.userAgent : process.platform);
|
|
@@ -2308,6 +2636,8 @@
|
|
|
2308
2636
|
},
|
|
2309
2637
|
],
|
|
2310
2638
|
nakaCommentSpeedOffset: 0.95,
|
|
2639
|
+
atButtonPadding: 5,
|
|
2640
|
+
atButtonRadius: 7,
|
|
2311
2641
|
};
|
|
2312
2642
|
updateConfig(defaultConfig);
|
|
2313
2643
|
};
|
|
@@ -2463,14 +2793,15 @@
|
|
|
2463
2793
|
mail: [],
|
|
2464
2794
|
user_id: -1,
|
|
2465
2795
|
layer: -1,
|
|
2796
|
+
is_my_post: false,
|
|
2466
2797
|
};
|
|
2467
2798
|
if (item.getAttribute("mail")) {
|
|
2468
|
-
tmpParam.mail = item.getAttribute("mail")?.split(/\s+/g)
|
|
2799
|
+
tmpParam.mail = item.getAttribute("mail")?.split(/\s+/g) ?? [];
|
|
2469
2800
|
}
|
|
2470
2801
|
if (tmpParam.content.startsWith("/") && tmpParam.owner) {
|
|
2471
2802
|
tmpParam.mail.push("invisible");
|
|
2472
2803
|
}
|
|
2473
|
-
const userId = item.getAttribute("user_id")
|
|
2804
|
+
const userId = item.getAttribute("user_id") ?? "";
|
|
2474
2805
|
const isUserExist = userList.indexOf(userId);
|
|
2475
2806
|
if (isUserExist === -1) {
|
|
2476
2807
|
tmpParam.user_id = userList.length;
|
|
@@ -2484,16 +2815,17 @@
|
|
|
2484
2815
|
return data_;
|
|
2485
2816
|
};
|
|
2486
2817
|
const fromFormatted = (data) => {
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2818
|
+
return data.map((comment) => {
|
|
2819
|
+
if (!typeGuard.formatted.comment(comment)) {
|
|
2820
|
+
return {
|
|
2821
|
+
...comment,
|
|
2822
|
+
layer: -1,
|
|
2823
|
+
user_id: 0,
|
|
2824
|
+
is_my_post: false,
|
|
2825
|
+
};
|
|
2494
2826
|
}
|
|
2495
|
-
|
|
2496
|
-
|
|
2827
|
+
return comment;
|
|
2828
|
+
});
|
|
2497
2829
|
};
|
|
2498
2830
|
const fromLegacy = (data) => {
|
|
2499
2831
|
const data_ = [], userList = [];
|
|
@@ -2513,6 +2845,7 @@
|
|
|
2513
2845
|
mail: [],
|
|
2514
2846
|
user_id: -1,
|
|
2515
2847
|
layer: -1,
|
|
2848
|
+
is_my_post: false,
|
|
2516
2849
|
};
|
|
2517
2850
|
if (value.mail) {
|
|
2518
2851
|
tmpParam.mail = value.mail.split(/\s+/g);
|
|
@@ -2551,7 +2884,7 @@
|
|
|
2551
2884
|
const tmpParam = {
|
|
2552
2885
|
id: i,
|
|
2553
2886
|
vpos: Number(commentData[0]) * 100,
|
|
2554
|
-
content: commentData[2]
|
|
2887
|
+
content: commentData[2] ?? "",
|
|
2555
2888
|
date: i,
|
|
2556
2889
|
date_usec: 0,
|
|
2557
2890
|
owner: true,
|
|
@@ -2559,6 +2892,7 @@
|
|
|
2559
2892
|
mail: [],
|
|
2560
2893
|
user_id: -1,
|
|
2561
2894
|
layer: -1,
|
|
2895
|
+
is_my_post: false,
|
|
2562
2896
|
};
|
|
2563
2897
|
if (commentData[1]) {
|
|
2564
2898
|
tmpParam.mail = commentData[1].split(/[\s+]/g);
|
|
@@ -2587,6 +2921,7 @@
|
|
|
2587
2921
|
mail: [],
|
|
2588
2922
|
user_id: -1,
|
|
2589
2923
|
layer: -1,
|
|
2924
|
+
is_my_post: false,
|
|
2590
2925
|
};
|
|
2591
2926
|
if (value.command) {
|
|
2592
2927
|
tmpParam.mail = value.command.split(/\s+/g);
|
|
@@ -2614,6 +2949,7 @@
|
|
|
2614
2949
|
mail: value.commands,
|
|
2615
2950
|
user_id: -1,
|
|
2616
2951
|
layer: -1,
|
|
2952
|
+
is_my_post: value.isMyPost,
|
|
2617
2953
|
};
|
|
2618
2954
|
if (tmpParam.content.startsWith("/") && tmpParam.owner) {
|
|
2619
2955
|
tmpParam.mail.push("invisible");
|
|
@@ -2650,7 +2986,7 @@
|
|
|
2650
2986
|
return data;
|
|
2651
2987
|
};
|
|
2652
2988
|
const time2vpos = (time_str) => {
|
|
2653
|
-
const time =
|
|
2989
|
+
const time = RegExp(/^(?:(\d+):(\d+)\.(\d+)|(\d+):(\d+)|(\d+)\.(\d+)|(\d+))$/).exec(time_str);
|
|
2654
2990
|
if (time) {
|
|
2655
2991
|
if (time[1] !== undefined &&
|
|
2656
2992
|
time[2] !== undefined &&
|
|
@@ -2706,7 +3042,6 @@
|
|
|
2706
3042
|
utils: index$1
|
|
2707
3043
|
});
|
|
2708
3044
|
|
|
2709
|
-
let isDebug = false;
|
|
2710
3045
|
class NiconiComments {
|
|
2711
3046
|
enableLegacyPiP;
|
|
2712
3047
|
showCollision;
|
|
@@ -2732,7 +3067,7 @@
|
|
|
2732
3067
|
throw new InvalidOptionError();
|
|
2733
3068
|
setOptions(Object.assign(defaultOptions, initOptions));
|
|
2734
3069
|
setConfig(Object.assign(defaultConfig, options.config));
|
|
2735
|
-
|
|
3070
|
+
setIsDebug(options.debug);
|
|
2736
3071
|
resetImageCache();
|
|
2737
3072
|
resetNicoScripts();
|
|
2738
3073
|
this.canvas = canvas;
|
|
@@ -2754,16 +3089,18 @@
|
|
|
2754
3089
|
options.mode = "html5";
|
|
2755
3090
|
}
|
|
2756
3091
|
const parsedData = convert2formattedComment(data, formatType);
|
|
2757
|
-
this.video = options.video
|
|
3092
|
+
this.video = options.video ?? undefined;
|
|
2758
3093
|
this.showCollision = options.showCollision;
|
|
2759
3094
|
this.showFPS = options.showFPS;
|
|
2760
3095
|
this.showCommentCount = options.showCommentCount;
|
|
2761
3096
|
this.enableLegacyPiP = options.enableLegacyPiP;
|
|
2762
3097
|
this.timeline = {};
|
|
2763
|
-
this.collision =
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
3098
|
+
this.collision = {
|
|
3099
|
+
ue: [],
|
|
3100
|
+
shita: [],
|
|
3101
|
+
left: [],
|
|
3102
|
+
right: [],
|
|
3103
|
+
};
|
|
2767
3104
|
this.lastVpos = -1;
|
|
2768
3105
|
this.preRendering(parsedData);
|
|
2769
3106
|
logger(`constructor complete: ${performance.now() - constructorStart}ms`);
|
|
@@ -2773,7 +3110,7 @@
|
|
|
2773
3110
|
if (options.keepCA) {
|
|
2774
3111
|
rawData = changeCALayer(rawData);
|
|
2775
3112
|
}
|
|
2776
|
-
|
|
3113
|
+
let instances = rawData.reduce((pv, val) => {
|
|
2777
3114
|
pv.push(createCommentInstance(val, this.context));
|
|
2778
3115
|
return pv;
|
|
2779
3116
|
}, []);
|
|
@@ -2782,7 +3119,15 @@
|
|
|
2782
3119
|
const plugins = [];
|
|
2783
3120
|
for (const plugin of config.plugins) {
|
|
2784
3121
|
try {
|
|
2785
|
-
|
|
3122
|
+
const canvas = generateCanvas();
|
|
3123
|
+
const pluginInstance = new plugin(canvas, instances);
|
|
3124
|
+
plugins.push({
|
|
3125
|
+
canvas,
|
|
3126
|
+
instance: pluginInstance,
|
|
3127
|
+
});
|
|
3128
|
+
if (pluginInstance.transformComments) {
|
|
3129
|
+
instances = pluginInstance.transformComments(instances);
|
|
3130
|
+
}
|
|
2786
3131
|
}
|
|
2787
3132
|
catch (e) {
|
|
2788
3133
|
console.error("Failed to init plugin");
|
|
@@ -2829,9 +3174,10 @@
|
|
|
2829
3174
|
pv.push(createCommentInstance(val, this.context));
|
|
2830
3175
|
return pv;
|
|
2831
3176
|
}, []);
|
|
3177
|
+
console.log(comments);
|
|
2832
3178
|
for (const plugin of plugins) {
|
|
2833
3179
|
try {
|
|
2834
|
-
plugin.addComments(comments);
|
|
3180
|
+
plugin.instance.addComments?.(comments);
|
|
2835
3181
|
}
|
|
2836
3182
|
catch (e) {
|
|
2837
3183
|
console.error("Failed to add comments");
|
|
@@ -2848,7 +3194,7 @@
|
|
|
2848
3194
|
}
|
|
2849
3195
|
}
|
|
2850
3196
|
}
|
|
2851
|
-
drawCanvas(vpos, forceRendering = false) {
|
|
3197
|
+
drawCanvas(vpos, forceRendering = false, cursor) {
|
|
2852
3198
|
const drawCanvasStart = performance.now();
|
|
2853
3199
|
if (this.lastVpos === vpos && !forceRendering)
|
|
2854
3200
|
return false;
|
|
@@ -2859,7 +3205,7 @@
|
|
|
2859
3205
|
timelineRange?.filter((item) => item.loc === "naka").length === 0 &&
|
|
2860
3206
|
this.timeline[this.lastVpos]?.filter((item) => item.loc === "naka")
|
|
2861
3207
|
?.length === 0) {
|
|
2862
|
-
const current = timelineRange.filter((item) => item.loc !== "naka"), last = this.timeline[this.lastVpos]?.filter((item) => item.loc !== "naka")
|
|
3208
|
+
const current = timelineRange.filter((item) => item.loc !== "naka"), last = this.timeline[this.lastVpos]?.filter((item) => item.loc !== "naka") ??
|
|
2863
3209
|
[];
|
|
2864
3210
|
if (ArrayEqual(current, last))
|
|
2865
3211
|
return false;
|
|
@@ -2867,16 +3213,17 @@
|
|
|
2867
3213
|
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
2868
3214
|
this.lastVpos = vpos;
|
|
2869
3215
|
this._drawVideo();
|
|
2870
|
-
this._drawCollision(vpos);
|
|
2871
|
-
this._drawComments(timelineRange, vpos);
|
|
2872
3216
|
for (const plugin of plugins) {
|
|
2873
3217
|
try {
|
|
2874
|
-
plugin.draw(vpos);
|
|
3218
|
+
plugin.instance.draw?.(vpos);
|
|
3219
|
+
this.context.drawImage(plugin.canvas, 0, 0);
|
|
2875
3220
|
}
|
|
2876
3221
|
catch (e) {
|
|
2877
3222
|
console.error(`Failed to draw comments`);
|
|
2878
3223
|
}
|
|
2879
3224
|
}
|
|
3225
|
+
this._drawCollision(vpos);
|
|
3226
|
+
this._drawComments(timelineRange, vpos, cursor);
|
|
2880
3227
|
this._drawFPS(drawCanvasStart);
|
|
2881
3228
|
this._drawCommentCount(timelineRange?.length);
|
|
2882
3229
|
logger(`drawCanvas complete: ${performance.now() - drawCanvasStart}ms`);
|
|
@@ -2896,7 +3243,7 @@
|
|
|
2896
3243
|
this.context.drawImage(this.video, offsetX, offsetY, this.video.videoWidth * scale, this.video.videoHeight * scale);
|
|
2897
3244
|
}
|
|
2898
3245
|
}
|
|
2899
|
-
_drawComments(timelineRange, vpos) {
|
|
3246
|
+
_drawComments(timelineRange, vpos, cursor) {
|
|
2900
3247
|
if (timelineRange) {
|
|
2901
3248
|
const targetComment = (() => {
|
|
2902
3249
|
if (config.commentLimit === undefined) {
|
|
@@ -2911,7 +3258,7 @@
|
|
|
2911
3258
|
if (comment.invisible) {
|
|
2912
3259
|
continue;
|
|
2913
3260
|
}
|
|
2914
|
-
comment.draw(vpos, this.showCollision,
|
|
3261
|
+
comment.draw(vpos, this.showCollision, cursor);
|
|
2915
3262
|
}
|
|
2916
3263
|
}
|
|
2917
3264
|
}
|
|
@@ -2952,8 +3299,8 @@
|
|
|
2952
3299
|
this.context.font = parseFont("defont", 60);
|
|
2953
3300
|
this.context.fillStyle = "#00FF00";
|
|
2954
3301
|
this.context.strokeStyle = `rgba(${hex2rgb(config.contextStrokeColor).join(",")},${config.contextStrokeOpacity})`;
|
|
2955
|
-
this.context.strokeText(`Count:${count
|
|
2956
|
-
this.context.fillText(`Count:${count
|
|
3302
|
+
this.context.strokeText(`Count:${count ?? 0}`, 100, 200);
|
|
3303
|
+
this.context.fillText(`Count:${count ?? 0}`, 100, 200);
|
|
2957
3304
|
this.context.restore();
|
|
2958
3305
|
}
|
|
2959
3306
|
}
|
|
@@ -2966,6 +3313,20 @@
|
|
|
2966
3313
|
clear() {
|
|
2967
3314
|
this.context.clearRect(0, 0, config.canvasWidth, config.canvasHeight);
|
|
2968
3315
|
}
|
|
3316
|
+
click(vpos, pos) {
|
|
3317
|
+
const _comments = this.timeline[vpos];
|
|
3318
|
+
if (!_comments)
|
|
3319
|
+
return;
|
|
3320
|
+
const comments = [..._comments].reverse();
|
|
3321
|
+
for (const comment of comments) {
|
|
3322
|
+
if (comment.isHovered(pos)) {
|
|
3323
|
+
const newComment = buildAtButtonComment(comment.comment, vpos);
|
|
3324
|
+
if (!newComment)
|
|
3325
|
+
continue;
|
|
3326
|
+
this.addComments(newComment);
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
2969
3330
|
}
|
|
2970
3331
|
const logger = (msg) => {
|
|
2971
3332
|
if (isDebug)
|