@xpadev-net/niconicomments 0.2.56 → 0.2.58
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 +439 -367
- package/dist/bundle.js +407 -110
- package/package.json +30 -28
package/dist/bundle.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
niconicomments.js v0.2.
|
|
2
|
+
niconicomments.js v0.2.58
|
|
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)) {
|
|
@@ -546,12 +555,12 @@
|
|
|
546
555
|
processNicoscript(comment, commands);
|
|
547
556
|
const defaultCommand = getDefaultCommand(comment.vpos);
|
|
548
557
|
applyNicoScriptReplace(comment, commands);
|
|
549
|
-
const size = commands.size
|
|
558
|
+
const size = commands.size ?? defaultCommand.size ?? "medium";
|
|
550
559
|
return {
|
|
551
560
|
size: size,
|
|
552
|
-
loc: commands.loc
|
|
553
|
-
color: commands.color
|
|
554
|
-
font: commands.font
|
|
561
|
+
loc: commands.loc ?? defaultCommand.loc ?? "naka",
|
|
562
|
+
color: commands.color ?? defaultCommand.color ?? "#FFFFFF",
|
|
563
|
+
font: commands.font ?? defaultCommand.font ?? "defont",
|
|
555
564
|
fontSize: getConfig(config.fontSize, isFlash)[size].default,
|
|
556
565
|
long: commands.long ? Math.floor(Number(commands.long) * 100) : 300,
|
|
557
566
|
flash: isFlash,
|
|
@@ -562,26 +571,27 @@
|
|
|
562
571
|
strokeColor: commands.strokeColor,
|
|
563
572
|
wakuColor: commands.wakuColor,
|
|
564
573
|
fillColor: commands.fillColor,
|
|
574
|
+
button: commands.button,
|
|
565
575
|
};
|
|
566
576
|
};
|
|
567
577
|
const parseBrackets = (input) => {
|
|
568
578
|
const content = input.split(""), result = [];
|
|
569
579
|
let quote = "", last_i = "", string = "";
|
|
570
580
|
for (const i of content) {
|
|
571
|
-
if (
|
|
581
|
+
if (RegExp(/^["'\u300c]$/).exec(i) && quote === "") {
|
|
572
582
|
quote = i;
|
|
573
583
|
}
|
|
574
|
-
else if (
|
|
584
|
+
else if (RegExp(/^["']$/).exec(i) && quote === i && last_i !== "\\") {
|
|
575
585
|
result.push(string.replaceAll("\\n", "\n"));
|
|
576
586
|
quote = "";
|
|
577
587
|
string = "";
|
|
578
588
|
}
|
|
579
|
-
else if (i
|
|
589
|
+
else if (i === "\u300d" && quote === "\u300c") {
|
|
580
590
|
result.push(string);
|
|
581
591
|
quote = "";
|
|
582
592
|
string = "";
|
|
583
593
|
}
|
|
584
|
-
else if (quote === "" &&
|
|
594
|
+
else if (quote === "" && RegExp(/^\s+$/).exec(i)) {
|
|
585
595
|
if (string) {
|
|
586
596
|
result.push(string);
|
|
587
597
|
string = "";
|
|
@@ -609,10 +619,10 @@
|
|
|
609
619
|
start: comment.vpos,
|
|
610
620
|
long: commands.long === undefined ? undefined : Math.floor(commands.long * 100),
|
|
611
621
|
keyword: result[0],
|
|
612
|
-
replace: result[1]
|
|
613
|
-
range: result[2]
|
|
614
|
-
target: result[3]
|
|
615
|
-
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",
|
|
616
626
|
color: commands.color,
|
|
617
627
|
size: commands.size,
|
|
618
628
|
font: commands.font,
|
|
@@ -635,11 +645,11 @@
|
|
|
635
645
|
});
|
|
636
646
|
};
|
|
637
647
|
const processNicoscript = (comment, commands) => {
|
|
638
|
-
const 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);
|
|
639
649
|
if (!nicoscript)
|
|
640
650
|
return;
|
|
641
651
|
if (nicoscript[1] === "\u30dc\u30bf\u30f3" && nicoscript[2]) {
|
|
642
|
-
processAtButton(commands);
|
|
652
|
+
processAtButton(comment, commands);
|
|
643
653
|
return;
|
|
644
654
|
}
|
|
645
655
|
if (!comment.owner)
|
|
@@ -680,8 +690,8 @@
|
|
|
680
690
|
});
|
|
681
691
|
};
|
|
682
692
|
const processReverseScript = (comment, commands) => {
|
|
683
|
-
const reverse =
|
|
684
|
-
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]))
|
|
685
695
|
return;
|
|
686
696
|
if (commands.long === undefined) {
|
|
687
697
|
commands.long = 30;
|
|
@@ -711,8 +721,8 @@
|
|
|
711
721
|
});
|
|
712
722
|
};
|
|
713
723
|
const processJumpScript$1 = (comment, commands, input) => {
|
|
714
|
-
const options =
|
|
715
|
-
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])
|
|
716
726
|
return;
|
|
717
727
|
nicoScripts.jump.unshift({
|
|
718
728
|
start: comment.vpos,
|
|
@@ -721,9 +731,26 @@
|
|
|
721
731
|
message: options[2],
|
|
722
732
|
});
|
|
723
733
|
};
|
|
724
|
-
const processAtButton = (commands) => {
|
|
734
|
+
const processAtButton = (comment, commands) => {
|
|
735
|
+
const args = parseBrackets(comment.content);
|
|
736
|
+
if (args[1] === undefined)
|
|
737
|
+
return;
|
|
725
738
|
commands.invisible = false;
|
|
726
|
-
|
|
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
|
+
};
|
|
727
754
|
};
|
|
728
755
|
const parseCommands = (comment) => {
|
|
729
756
|
const commands = comment.mail, isFlash = isFlashComment(comment);
|
|
@@ -740,7 +767,6 @@
|
|
|
740
767
|
_live: false,
|
|
741
768
|
invisible: false,
|
|
742
769
|
long: undefined,
|
|
743
|
-
button: false,
|
|
744
770
|
};
|
|
745
771
|
for (const command of commands) {
|
|
746
772
|
parseCommand(comment, command, result, isFlash);
|
|
@@ -752,22 +778,22 @@
|
|
|
752
778
|
};
|
|
753
779
|
const parseCommand = (comment, _command, result, isFlash) => {
|
|
754
780
|
const command = _command.toLowerCase();
|
|
755
|
-
const long =
|
|
781
|
+
const long = RegExp(/^[@\uff20]([0-9.]+)/).exec(command);
|
|
756
782
|
if (long) {
|
|
757
783
|
result.long = Number(long[1]);
|
|
758
784
|
return;
|
|
759
785
|
}
|
|
760
|
-
const strokeColor = getColor(
|
|
786
|
+
const strokeColor = getColor(RegExp(/^nico:stroke:(.+)$/).exec(command));
|
|
761
787
|
if (strokeColor) {
|
|
762
788
|
result.strokeColor ??= strokeColor;
|
|
763
789
|
return;
|
|
764
790
|
}
|
|
765
|
-
const rectColor = getColor(
|
|
791
|
+
const rectColor = getColor(RegExp(/^nico:waku:(.+)$/).exec(command));
|
|
766
792
|
if (rectColor) {
|
|
767
793
|
result.wakuColor ??= rectColor;
|
|
768
794
|
return;
|
|
769
795
|
}
|
|
770
|
-
const fillColor = getColor(
|
|
796
|
+
const fillColor = getColor(RegExp(/^nico:fill:(.+)$/).exec(command));
|
|
771
797
|
if (fillColor) {
|
|
772
798
|
result.fillColor ??= fillColor;
|
|
773
799
|
return;
|
|
@@ -785,7 +811,7 @@
|
|
|
785
811
|
result.color ??= config.colors[command];
|
|
786
812
|
return;
|
|
787
813
|
}
|
|
788
|
-
const colorCode =
|
|
814
|
+
const colorCode = RegExp(/^#(?:[0-9a-z]{3}|[0-9a-z]{6})$/).exec(command);
|
|
789
815
|
if (colorCode && comment.premium) {
|
|
790
816
|
result.color ??= colorCode[0].toUpperCase();
|
|
791
817
|
return;
|
|
@@ -970,7 +996,7 @@
|
|
|
970
996
|
const changeCALayer = (rawData) => {
|
|
971
997
|
const userScoreList = getUsersScore(rawData);
|
|
972
998
|
const filteredComments = removeDuplicateCommentArt(rawData);
|
|
973
|
-
const commentArts = filteredComments.filter((comment) => (userScoreList[comment.user_id]
|
|
999
|
+
const commentArts = filteredComments.filter((comment) => (userScoreList[comment.user_id] ?? 0) >= config.sameCAMinScore &&
|
|
974
1000
|
!comment.owner);
|
|
975
1001
|
const commentArtsGroupedByUser = groupCommentsByUser(commentArts);
|
|
976
1002
|
const commentArtsGroupedByTimes = groupCommentsByTime(commentArtsGroupedByUser);
|
|
@@ -989,7 +1015,7 @@
|
|
|
989
1015
|
comment.mail.includes("full")) {
|
|
990
1016
|
userScoreList[comment.user_id] += 5;
|
|
991
1017
|
}
|
|
992
|
-
const lineCount = (comment.content.match(/\r\n|\n|\r/g)
|
|
1018
|
+
const lineCount = (comment.content.match(/\r\n|\n|\r/g) ?? []).length;
|
|
993
1019
|
if (lineCount > 2) {
|
|
994
1020
|
userScoreList[comment.user_id] += lineCount / 2;
|
|
995
1021
|
}
|
|
@@ -1001,7 +1027,7 @@
|
|
|
1001
1027
|
return comments.filter((comment) => {
|
|
1002
1028
|
const key = `${comment.content}@@${[...comment.mail]
|
|
1003
1029
|
.sort()
|
|
1004
|
-
.filter((e) => !
|
|
1030
|
+
.filter((e) => !RegExp(/@[\d.]+|184|device:.+|patissier|ca/).exec(e))
|
|
1005
1031
|
.join("")}`, lastComment = index[key];
|
|
1006
1032
|
if (lastComment === undefined) {
|
|
1007
1033
|
index[key] = comment;
|
|
@@ -1121,11 +1147,11 @@
|
|
|
1121
1147
|
};
|
|
1122
1148
|
const parseContent = (content) => {
|
|
1123
1149
|
const results = [];
|
|
1124
|
-
const lines = (content.match(/\n|[^\n]+/g)
|
|
1150
|
+
const lines = Array.from(content.match(/\n|[^\n]+/g) ?? []);
|
|
1125
1151
|
for (const line of lines) {
|
|
1126
1152
|
const lineContent = parseLine(line);
|
|
1127
1153
|
const firstContent = lineContent[0];
|
|
1128
|
-
if (firstContent
|
|
1154
|
+
if (firstContent?.font) {
|
|
1129
1155
|
results.push(...lineContent.map((val) => {
|
|
1130
1156
|
if (!val.font) {
|
|
1131
1157
|
val.font = firstContent.font;
|
|
@@ -1140,8 +1166,9 @@
|
|
|
1140
1166
|
return results;
|
|
1141
1167
|
};
|
|
1142
1168
|
const parseLine = (line) => {
|
|
1169
|
+
const parts = Array.from(line.match(/[ -~。-゚]+|[^ -~。-゚]+/g) ?? []);
|
|
1143
1170
|
const lineContent = [];
|
|
1144
|
-
for (const part of
|
|
1171
|
+
for (const part of parts) {
|
|
1145
1172
|
if (part.match(/[ -~。-゚]+/g) !== null) {
|
|
1146
1173
|
lineContent.push({ content: part, slicedContent: part.split("\n") });
|
|
1147
1174
|
continue;
|
|
@@ -1222,6 +1249,108 @@
|
|
|
1222
1249
|
font: getFlashFontName(secondVal.font),
|
|
1223
1250
|
});
|
|
1224
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
|
+
};
|
|
1225
1354
|
|
|
1226
1355
|
class TypeGuardError extends Error {
|
|
1227
1356
|
constructor(options = {}) {
|
|
@@ -1257,7 +1386,7 @@
|
|
|
1257
1386
|
let currentWidth = 0;
|
|
1258
1387
|
for (const item of comment.content) {
|
|
1259
1388
|
const lines = item.content.split("\n");
|
|
1260
|
-
context.font = parseFont(item.font
|
|
1389
|
+
context.font = parseFont(item.font ?? comment.font, fontSize);
|
|
1261
1390
|
const width = [];
|
|
1262
1391
|
for (let j = 0, n = lines.length; j < n; j++) {
|
|
1263
1392
|
const line = lines[j];
|
|
@@ -1300,7 +1429,9 @@
|
|
|
1300
1429
|
__proto__: null,
|
|
1301
1430
|
ArrayEqual: ArrayEqual,
|
|
1302
1431
|
ArrayPush: ArrayPush,
|
|
1432
|
+
buildAtButtonComment: buildAtButtonComment,
|
|
1303
1433
|
changeCALayer: changeCALayer,
|
|
1434
|
+
getButtonParts: getButtonParts,
|
|
1304
1435
|
getCharSize: getCharSize,
|
|
1305
1436
|
getConfig: getConfig,
|
|
1306
1437
|
getDefaultCommand: getDefaultCommand,
|
|
@@ -1343,12 +1474,15 @@
|
|
|
1343
1474
|
context;
|
|
1344
1475
|
cacheKey;
|
|
1345
1476
|
comment;
|
|
1477
|
+
pos;
|
|
1346
1478
|
posY;
|
|
1347
1479
|
pluginName = "BaseComment";
|
|
1348
1480
|
image;
|
|
1481
|
+
buttonImage;
|
|
1349
1482
|
constructor(comment, context) {
|
|
1350
1483
|
this.context = context;
|
|
1351
1484
|
this.posY = 0;
|
|
1485
|
+
this.pos = { x: 0, y: 0 };
|
|
1352
1486
|
comment.content = comment.content.replace(/\t/g, "\u2003\u2003");
|
|
1353
1487
|
this.comment = this.convertComment(comment);
|
|
1354
1488
|
this.cacheKey =
|
|
@@ -1412,7 +1546,7 @@
|
|
|
1412
1546
|
console.error("convertComment method is not implemented", comment);
|
|
1413
1547
|
throw new NotImplementedError(this.pluginName, "convertComment");
|
|
1414
1548
|
}
|
|
1415
|
-
draw(vpos, showCollision,
|
|
1549
|
+
draw(vpos, showCollision, cursor) {
|
|
1416
1550
|
if (isBanActive(vpos))
|
|
1417
1551
|
return;
|
|
1418
1552
|
const reverse = isReverseActive(vpos, this.comment.owner);
|
|
@@ -1420,13 +1554,17 @@
|
|
|
1420
1554
|
const posY = this.comment.loc === "shita"
|
|
1421
1555
|
? config.canvasHeight - this.posY - this.comment.height
|
|
1422
1556
|
: this.posY;
|
|
1557
|
+
this.pos = {
|
|
1558
|
+
x: posX,
|
|
1559
|
+
y: posY,
|
|
1560
|
+
};
|
|
1423
1561
|
this._drawBackgroundColor(posX, posY);
|
|
1424
|
-
this._draw(posX, posY);
|
|
1562
|
+
this._draw(posX, posY, cursor);
|
|
1425
1563
|
this._drawRectColor(posX, posY);
|
|
1426
1564
|
this._drawCollision(posX, posY, showCollision);
|
|
1427
|
-
this._drawDebugInfo(posX, posY
|
|
1565
|
+
this._drawDebugInfo(posX, posY);
|
|
1428
1566
|
}
|
|
1429
|
-
_draw(posX, posY) {
|
|
1567
|
+
_draw(posX, posY, cursor) {
|
|
1430
1568
|
if (this.image === undefined) {
|
|
1431
1569
|
this.image = this.getTextImage();
|
|
1432
1570
|
}
|
|
@@ -1438,6 +1576,10 @@
|
|
|
1438
1576
|
else {
|
|
1439
1577
|
this.context.globalAlpha = 1;
|
|
1440
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
|
+
}
|
|
1441
1583
|
drawImage(this.context, this.image, posX, posY);
|
|
1442
1584
|
this.context.restore();
|
|
1443
1585
|
}
|
|
@@ -1458,8 +1600,8 @@
|
|
|
1458
1600
|
this.context.restore();
|
|
1459
1601
|
}
|
|
1460
1602
|
}
|
|
1461
|
-
_drawDebugInfo(posX, posY
|
|
1462
|
-
if (
|
|
1603
|
+
_drawDebugInfo(posX, posY) {
|
|
1604
|
+
if (isDebug) {
|
|
1463
1605
|
this.context.save();
|
|
1464
1606
|
const font = this.context.font;
|
|
1465
1607
|
const fillStyle = this.context.fillStyle;
|
|
@@ -1523,14 +1665,60 @@
|
|
|
1523
1665
|
context,
|
|
1524
1666
|
};
|
|
1525
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
|
+
}
|
|
1526
1676
|
}
|
|
1527
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
|
+
|
|
1528
1711
|
class FlashComment extends BaseComment {
|
|
1529
1712
|
_globalScale;
|
|
1530
1713
|
pluginName = "FlashComment";
|
|
1714
|
+
buttonImage;
|
|
1715
|
+
buttonContext;
|
|
1531
1716
|
constructor(comment, context) {
|
|
1532
1717
|
super(comment, context);
|
|
1533
1718
|
this._globalScale ??= getConfig(config.commentScale, true);
|
|
1719
|
+
const button = this.createCanvas();
|
|
1720
|
+
this.buttonImage = button.image;
|
|
1721
|
+
this.buttonContext = button.context;
|
|
1534
1722
|
}
|
|
1535
1723
|
get content() {
|
|
1536
1724
|
return this.comment.rawContent;
|
|
@@ -1545,7 +1733,7 @@
|
|
|
1545
1733
|
lineOffset,
|
|
1546
1734
|
};
|
|
1547
1735
|
const val = content[0];
|
|
1548
|
-
if (val
|
|
1736
|
+
if (val?.font) {
|
|
1549
1737
|
comment.font = val.font;
|
|
1550
1738
|
}
|
|
1551
1739
|
this.comment = this.getCommentSize(comment);
|
|
@@ -1557,7 +1745,7 @@
|
|
|
1557
1745
|
}
|
|
1558
1746
|
convertComment(comment) {
|
|
1559
1747
|
this._globalScale = getConfig(config.commentScale, true);
|
|
1560
|
-
return this.getCommentSize(this.parseCommandAndNicoscript(comment));
|
|
1748
|
+
return getButtonParts(this.getCommentSize(this.parseCommandAndNicoscript(comment)));
|
|
1561
1749
|
}
|
|
1562
1750
|
getCommentSize(parsedData) {
|
|
1563
1751
|
if (parsedData.invisible) {
|
|
@@ -1584,6 +1772,9 @@
|
|
|
1584
1772
|
measure.width *= options.scale;
|
|
1585
1773
|
}
|
|
1586
1774
|
this.context.restore();
|
|
1775
|
+
if (parsedData.button && !parsedData.button.hidden) {
|
|
1776
|
+
measure.width += getConfig(config.atButtonPadding, true) * 4;
|
|
1777
|
+
}
|
|
1587
1778
|
return {
|
|
1588
1779
|
...parsedData,
|
|
1589
1780
|
height: measure.height * this._globalScale,
|
|
@@ -1601,9 +1792,9 @@
|
|
|
1601
1792
|
}
|
|
1602
1793
|
parseCommandAndNicoscript(comment) {
|
|
1603
1794
|
const data = parseCommandAndNicoScript(comment);
|
|
1604
|
-
const { content, lineCount, lineOffset } = this.parseContent(comment.content);
|
|
1795
|
+
const { content, lineCount, lineOffset } = this.parseContent(comment.content, data.button);
|
|
1605
1796
|
const val = content[0];
|
|
1606
|
-
if (val
|
|
1797
|
+
if (val?.font) {
|
|
1607
1798
|
data.font = val.font;
|
|
1608
1799
|
}
|
|
1609
1800
|
return {
|
|
@@ -1615,16 +1806,23 @@
|
|
|
1615
1806
|
lineOffset,
|
|
1616
1807
|
};
|
|
1617
1808
|
}
|
|
1618
|
-
parseContent(input) {
|
|
1619
|
-
const content =
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
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 ??
|
|
1624
1822
|
0) *
|
|
1625
1823
|
-1 *
|
|
1626
1824
|
config.scriptCharOffset +
|
|
1627
|
-
(input.match(new RegExp(config.FlashScriptChar.sub, "g"))?.length
|
|
1825
|
+
(input.match(new RegExp(config.FlashScriptChar.sub, "g"))?.length ?? 0) *
|
|
1628
1826
|
config.scriptCharOffset;
|
|
1629
1827
|
return {
|
|
1630
1828
|
content,
|
|
@@ -1694,7 +1892,7 @@
|
|
|
1694
1892
|
for (const item of comment.content) {
|
|
1695
1893
|
const lines = item.content.split("\n");
|
|
1696
1894
|
const widths = [];
|
|
1697
|
-
this.context.font = parseFont(item.font
|
|
1895
|
+
this.context.font = parseFont(item.font ?? comment.font, comment.fontSize);
|
|
1698
1896
|
for (let i = 0, n = lines.length; i < n; i++) {
|
|
1699
1897
|
const value = lines[i];
|
|
1700
1898
|
if (value === undefined)
|
|
@@ -1739,27 +1937,19 @@
|
|
|
1739
1937
|
}
|
|
1740
1938
|
_generateTextImage() {
|
|
1741
1939
|
const { image, context } = this.createCanvas();
|
|
1742
|
-
image
|
|
1743
|
-
|
|
1744
|
-
context.strokeStyle = getStrokeColor(this.comment);
|
|
1745
|
-
context.fillStyle = this.comment.color;
|
|
1746
|
-
context.textAlign = "start";
|
|
1747
|
-
context.textBaseline = "alphabetic";
|
|
1748
|
-
context.lineWidth = 4;
|
|
1749
|
-
context.font = parseFont(this.comment.font, this.comment.fontSize);
|
|
1750
|
-
const scale = this._globalScale *
|
|
1751
|
-
this.comment.scale *
|
|
1752
|
-
(this.comment.layer === -1 ? options.scale : 1);
|
|
1753
|
-
context.scale(scale * this.comment.scaleX, scale);
|
|
1940
|
+
this._setupCanvas(image, context);
|
|
1941
|
+
const atButtonPadding = getConfig(config.atButtonPadding, true);
|
|
1754
1942
|
const lineOffset = this.comment.lineOffset;
|
|
1943
|
+
const lineHeight = this.comment.fontSize * this.comment.lineHeight;
|
|
1755
1944
|
const offsetKey = this.comment.resizedY ? "resized" : "default";
|
|
1756
1945
|
const offsetY = config.commentYPaddingTop[offsetKey] +
|
|
1757
1946
|
this.comment.fontSize *
|
|
1758
1947
|
this.comment.lineHeight *
|
|
1759
1948
|
config.commentYOffset[this.comment.size][offsetKey];
|
|
1760
|
-
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);
|
|
1761
1951
|
for (const item of this.comment.content) {
|
|
1762
|
-
const font = item.font
|
|
1952
|
+
const font = item.font ?? this.comment.font;
|
|
1763
1953
|
if (lastFont !== font) {
|
|
1764
1954
|
lastFont = font;
|
|
1765
1955
|
context.font = parseFont(font, this.comment.fontSize);
|
|
@@ -1769,9 +1959,16 @@
|
|
|
1769
1959
|
const line = lines[j];
|
|
1770
1960
|
if (line === undefined)
|
|
1771
1961
|
continue;
|
|
1772
|
-
const posY = (lineOffset + lineCount + 1) *
|
|
1773
|
-
|
|
1774
|
-
|
|
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
|
+
}
|
|
1775
1972
|
context.strokeText(line, leftOffset, posY);
|
|
1776
1973
|
context.fillText(line, leftOffset, posY);
|
|
1777
1974
|
if (j < n - 1) {
|
|
@@ -1779,11 +1976,79 @@
|
|
|
1779
1976
|
lineCount += 1;
|
|
1780
1977
|
continue;
|
|
1781
1978
|
}
|
|
1782
|
-
leftOffset +=
|
|
1979
|
+
leftOffset += partWidth;
|
|
1783
1980
|
}
|
|
1981
|
+
isLastButton = !!item.isButton;
|
|
1784
1982
|
}
|
|
1785
1983
|
return image;
|
|
1786
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
|
+
}
|
|
1787
2052
|
}
|
|
1788
2053
|
|
|
1789
2054
|
class HTML5Comment extends BaseComment {
|
|
@@ -1875,7 +2140,7 @@
|
|
|
1875
2140
|
slicedContent: input.split("\n"),
|
|
1876
2141
|
});
|
|
1877
2142
|
const lineCount = content.reduce((pv, val) => {
|
|
1878
|
-
return pv + (val.content.match(/\n/g)?.length
|
|
2143
|
+
return pv + (val.content.match(/\n/g)?.length ?? 0);
|
|
1879
2144
|
}, 1);
|
|
1880
2145
|
const lineOffset = 0;
|
|
1881
2146
|
return {
|
|
@@ -2044,6 +2309,12 @@
|
|
|
2044
2309
|
}
|
|
2045
2310
|
return image;
|
|
2046
2311
|
}
|
|
2312
|
+
getButtonImage() {
|
|
2313
|
+
return undefined;
|
|
2314
|
+
}
|
|
2315
|
+
isHovered() {
|
|
2316
|
+
return false;
|
|
2317
|
+
}
|
|
2047
2318
|
}
|
|
2048
2319
|
|
|
2049
2320
|
var index = /*#__PURE__*/Object.freeze({
|
|
@@ -2199,17 +2470,17 @@
|
|
|
2199
2470
|
|
|
2200
2471
|
const initConfig = () => {
|
|
2201
2472
|
const platform = (function (ua) {
|
|
2202
|
-
if (
|
|
2473
|
+
if (RegExp(/windows nt 6\.[12]/i).exec(ua))
|
|
2203
2474
|
return "win7";
|
|
2204
|
-
else if (
|
|
2475
|
+
else if (RegExp(/windows nt (6\.3|10\.\d+)|win32/i).exec(ua))
|
|
2205
2476
|
return "win8_1";
|
|
2206
|
-
else if (
|
|
2477
|
+
else if (RegExp(/windows nt/i).exec(ua))
|
|
2207
2478
|
return "win";
|
|
2208
|
-
else if (
|
|
2479
|
+
else if (RegExp(/mac os x 10(.|_)(9|10)/i).exec(ua))
|
|
2209
2480
|
return "mac10_9";
|
|
2210
|
-
else if (
|
|
2481
|
+
else if (RegExp(/mac os x 10(.|_)\d{2}|darwin/i).exec(ua))
|
|
2211
2482
|
return "mac10_11";
|
|
2212
|
-
else if (
|
|
2483
|
+
else if (RegExp(/mac os x/i).exec(ua))
|
|
2213
2484
|
return "mac";
|
|
2214
2485
|
return "other";
|
|
2215
2486
|
})(typeof navigator !== "undefined" ? navigator.userAgent : process.platform);
|
|
@@ -2365,6 +2636,8 @@
|
|
|
2365
2636
|
},
|
|
2366
2637
|
],
|
|
2367
2638
|
nakaCommentSpeedOffset: 0.95,
|
|
2639
|
+
atButtonPadding: 5,
|
|
2640
|
+
atButtonRadius: 7,
|
|
2368
2641
|
};
|
|
2369
2642
|
updateConfig(defaultConfig);
|
|
2370
2643
|
};
|
|
@@ -2520,14 +2793,15 @@
|
|
|
2520
2793
|
mail: [],
|
|
2521
2794
|
user_id: -1,
|
|
2522
2795
|
layer: -1,
|
|
2796
|
+
is_my_post: false,
|
|
2523
2797
|
};
|
|
2524
2798
|
if (item.getAttribute("mail")) {
|
|
2525
|
-
tmpParam.mail = item.getAttribute("mail")?.split(/\s+/g)
|
|
2799
|
+
tmpParam.mail = item.getAttribute("mail")?.split(/\s+/g) ?? [];
|
|
2526
2800
|
}
|
|
2527
2801
|
if (tmpParam.content.startsWith("/") && tmpParam.owner) {
|
|
2528
2802
|
tmpParam.mail.push("invisible");
|
|
2529
2803
|
}
|
|
2530
|
-
const userId = item.getAttribute("user_id")
|
|
2804
|
+
const userId = item.getAttribute("user_id") ?? "";
|
|
2531
2805
|
const isUserExist = userList.indexOf(userId);
|
|
2532
2806
|
if (isUserExist === -1) {
|
|
2533
2807
|
tmpParam.user_id = userList.length;
|
|
@@ -2542,11 +2816,12 @@
|
|
|
2542
2816
|
};
|
|
2543
2817
|
const fromFormatted = (data) => {
|
|
2544
2818
|
return data.map((comment) => {
|
|
2545
|
-
if (typeGuard.formatted.
|
|
2819
|
+
if (!typeGuard.formatted.comment(comment)) {
|
|
2546
2820
|
return {
|
|
2547
2821
|
...comment,
|
|
2548
2822
|
layer: -1,
|
|
2549
2823
|
user_id: 0,
|
|
2824
|
+
is_my_post: false,
|
|
2550
2825
|
};
|
|
2551
2826
|
}
|
|
2552
2827
|
return comment;
|
|
@@ -2570,6 +2845,7 @@
|
|
|
2570
2845
|
mail: [],
|
|
2571
2846
|
user_id: -1,
|
|
2572
2847
|
layer: -1,
|
|
2848
|
+
is_my_post: false,
|
|
2573
2849
|
};
|
|
2574
2850
|
if (value.mail) {
|
|
2575
2851
|
tmpParam.mail = value.mail.split(/\s+/g);
|
|
@@ -2608,7 +2884,7 @@
|
|
|
2608
2884
|
const tmpParam = {
|
|
2609
2885
|
id: i,
|
|
2610
2886
|
vpos: Number(commentData[0]) * 100,
|
|
2611
|
-
content: commentData[2]
|
|
2887
|
+
content: commentData[2] ?? "",
|
|
2612
2888
|
date: i,
|
|
2613
2889
|
date_usec: 0,
|
|
2614
2890
|
owner: true,
|
|
@@ -2616,6 +2892,7 @@
|
|
|
2616
2892
|
mail: [],
|
|
2617
2893
|
user_id: -1,
|
|
2618
2894
|
layer: -1,
|
|
2895
|
+
is_my_post: false,
|
|
2619
2896
|
};
|
|
2620
2897
|
if (commentData[1]) {
|
|
2621
2898
|
tmpParam.mail = commentData[1].split(/[\s+]/g);
|
|
@@ -2644,6 +2921,7 @@
|
|
|
2644
2921
|
mail: [],
|
|
2645
2922
|
user_id: -1,
|
|
2646
2923
|
layer: -1,
|
|
2924
|
+
is_my_post: false,
|
|
2647
2925
|
};
|
|
2648
2926
|
if (value.command) {
|
|
2649
2927
|
tmpParam.mail = value.command.split(/\s+/g);
|
|
@@ -2671,6 +2949,7 @@
|
|
|
2671
2949
|
mail: value.commands,
|
|
2672
2950
|
user_id: -1,
|
|
2673
2951
|
layer: -1,
|
|
2952
|
+
is_my_post: value.isMyPost,
|
|
2674
2953
|
};
|
|
2675
2954
|
if (tmpParam.content.startsWith("/") && tmpParam.owner) {
|
|
2676
2955
|
tmpParam.mail.push("invisible");
|
|
@@ -2707,7 +2986,7 @@
|
|
|
2707
2986
|
return data;
|
|
2708
2987
|
};
|
|
2709
2988
|
const time2vpos = (time_str) => {
|
|
2710
|
-
const time =
|
|
2989
|
+
const time = RegExp(/^(?:(\d+):(\d+)\.(\d+)|(\d+):(\d+)|(\d+)\.(\d+)|(\d+))$/).exec(time_str);
|
|
2711
2990
|
if (time) {
|
|
2712
2991
|
if (time[1] !== undefined &&
|
|
2713
2992
|
time[2] !== undefined &&
|
|
@@ -2763,7 +3042,6 @@
|
|
|
2763
3042
|
utils: index$1
|
|
2764
3043
|
});
|
|
2765
3044
|
|
|
2766
|
-
let isDebug = false;
|
|
2767
3045
|
class NiconiComments {
|
|
2768
3046
|
enableLegacyPiP;
|
|
2769
3047
|
showCollision;
|
|
@@ -2789,7 +3067,7 @@
|
|
|
2789
3067
|
throw new InvalidOptionError();
|
|
2790
3068
|
setOptions(Object.assign(defaultOptions, initOptions));
|
|
2791
3069
|
setConfig(Object.assign(defaultConfig, options.config));
|
|
2792
|
-
|
|
3070
|
+
setIsDebug(options.debug);
|
|
2793
3071
|
resetImageCache();
|
|
2794
3072
|
resetNicoScripts();
|
|
2795
3073
|
this.canvas = canvas;
|
|
@@ -2811,7 +3089,7 @@
|
|
|
2811
3089
|
options.mode = "html5";
|
|
2812
3090
|
}
|
|
2813
3091
|
const parsedData = convert2formattedComment(data, formatType);
|
|
2814
|
-
this.video = options.video
|
|
3092
|
+
this.video = options.video ?? undefined;
|
|
2815
3093
|
this.showCollision = options.showCollision;
|
|
2816
3094
|
this.showFPS = options.showFPS;
|
|
2817
3095
|
this.showCommentCount = options.showCommentCount;
|
|
@@ -2832,7 +3110,7 @@
|
|
|
2832
3110
|
if (options.keepCA) {
|
|
2833
3111
|
rawData = changeCALayer(rawData);
|
|
2834
3112
|
}
|
|
2835
|
-
|
|
3113
|
+
let instances = rawData.reduce((pv, val) => {
|
|
2836
3114
|
pv.push(createCommentInstance(val, this.context));
|
|
2837
3115
|
return pv;
|
|
2838
3116
|
}, []);
|
|
@@ -2842,10 +3120,14 @@
|
|
|
2842
3120
|
for (const plugin of config.plugins) {
|
|
2843
3121
|
try {
|
|
2844
3122
|
const canvas = generateCanvas();
|
|
3123
|
+
const pluginInstance = new plugin(canvas, instances);
|
|
2845
3124
|
plugins.push({
|
|
2846
3125
|
canvas,
|
|
2847
|
-
instance:
|
|
3126
|
+
instance: pluginInstance,
|
|
2848
3127
|
});
|
|
3128
|
+
if (pluginInstance.transformComments) {
|
|
3129
|
+
instances = pluginInstance.transformComments(instances);
|
|
3130
|
+
}
|
|
2849
3131
|
}
|
|
2850
3132
|
catch (e) {
|
|
2851
3133
|
console.error("Failed to init plugin");
|
|
@@ -2892,9 +3174,10 @@
|
|
|
2892
3174
|
pv.push(createCommentInstance(val, this.context));
|
|
2893
3175
|
return pv;
|
|
2894
3176
|
}, []);
|
|
3177
|
+
console.log(comments);
|
|
2895
3178
|
for (const plugin of plugins) {
|
|
2896
3179
|
try {
|
|
2897
|
-
plugin.instance.addComments(comments);
|
|
3180
|
+
plugin.instance.addComments?.(comments);
|
|
2898
3181
|
}
|
|
2899
3182
|
catch (e) {
|
|
2900
3183
|
console.error("Failed to add comments");
|
|
@@ -2911,7 +3194,7 @@
|
|
|
2911
3194
|
}
|
|
2912
3195
|
}
|
|
2913
3196
|
}
|
|
2914
|
-
drawCanvas(vpos, forceRendering = false) {
|
|
3197
|
+
drawCanvas(vpos, forceRendering = false, cursor) {
|
|
2915
3198
|
const drawCanvasStart = performance.now();
|
|
2916
3199
|
if (this.lastVpos === vpos && !forceRendering)
|
|
2917
3200
|
return false;
|
|
@@ -2922,7 +3205,7 @@
|
|
|
2922
3205
|
timelineRange?.filter((item) => item.loc === "naka").length === 0 &&
|
|
2923
3206
|
this.timeline[this.lastVpos]?.filter((item) => item.loc === "naka")
|
|
2924
3207
|
?.length === 0) {
|
|
2925
|
-
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") ??
|
|
2926
3209
|
[];
|
|
2927
3210
|
if (ArrayEqual(current, last))
|
|
2928
3211
|
return false;
|
|
@@ -2930,17 +3213,17 @@
|
|
|
2930
3213
|
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
2931
3214
|
this.lastVpos = vpos;
|
|
2932
3215
|
this._drawVideo();
|
|
2933
|
-
this._drawCollision(vpos);
|
|
2934
|
-
this._drawComments(timelineRange, vpos);
|
|
2935
3216
|
for (const plugin of plugins) {
|
|
2936
3217
|
try {
|
|
2937
|
-
plugin.instance.draw(vpos);
|
|
3218
|
+
plugin.instance.draw?.(vpos);
|
|
2938
3219
|
this.context.drawImage(plugin.canvas, 0, 0);
|
|
2939
3220
|
}
|
|
2940
3221
|
catch (e) {
|
|
2941
3222
|
console.error(`Failed to draw comments`);
|
|
2942
3223
|
}
|
|
2943
3224
|
}
|
|
3225
|
+
this._drawCollision(vpos);
|
|
3226
|
+
this._drawComments(timelineRange, vpos, cursor);
|
|
2944
3227
|
this._drawFPS(drawCanvasStart);
|
|
2945
3228
|
this._drawCommentCount(timelineRange?.length);
|
|
2946
3229
|
logger(`drawCanvas complete: ${performance.now() - drawCanvasStart}ms`);
|
|
@@ -2960,7 +3243,7 @@
|
|
|
2960
3243
|
this.context.drawImage(this.video, offsetX, offsetY, this.video.videoWidth * scale, this.video.videoHeight * scale);
|
|
2961
3244
|
}
|
|
2962
3245
|
}
|
|
2963
|
-
_drawComments(timelineRange, vpos) {
|
|
3246
|
+
_drawComments(timelineRange, vpos, cursor) {
|
|
2964
3247
|
if (timelineRange) {
|
|
2965
3248
|
const targetComment = (() => {
|
|
2966
3249
|
if (config.commentLimit === undefined) {
|
|
@@ -2975,7 +3258,7 @@
|
|
|
2975
3258
|
if (comment.invisible) {
|
|
2976
3259
|
continue;
|
|
2977
3260
|
}
|
|
2978
|
-
comment.draw(vpos, this.showCollision,
|
|
3261
|
+
comment.draw(vpos, this.showCollision, cursor);
|
|
2979
3262
|
}
|
|
2980
3263
|
}
|
|
2981
3264
|
}
|
|
@@ -3016,8 +3299,8 @@
|
|
|
3016
3299
|
this.context.font = parseFont("defont", 60);
|
|
3017
3300
|
this.context.fillStyle = "#00FF00";
|
|
3018
3301
|
this.context.strokeStyle = `rgba(${hex2rgb(config.contextStrokeColor).join(",")},${config.contextStrokeOpacity})`;
|
|
3019
|
-
this.context.strokeText(`Count:${count
|
|
3020
|
-
this.context.fillText(`Count:${count
|
|
3302
|
+
this.context.strokeText(`Count:${count ?? 0}`, 100, 200);
|
|
3303
|
+
this.context.fillText(`Count:${count ?? 0}`, 100, 200);
|
|
3021
3304
|
this.context.restore();
|
|
3022
3305
|
}
|
|
3023
3306
|
}
|
|
@@ -3030,6 +3313,20 @@
|
|
|
3030
3313
|
clear() {
|
|
3031
3314
|
this.context.clearRect(0, 0, config.canvasWidth, config.canvasHeight);
|
|
3032
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
|
+
}
|
|
3033
3330
|
}
|
|
3034
3331
|
const logger = (msg) => {
|
|
3035
3332
|
if (isDebug)
|