// ==UserScript==
// @name ニコニコ静画、簡単NGスクリプト
// @namespace http://tampermonkey.net/
// @version 1.398
// @description 申し訳ないが見たくないイラストはNG
// @author cbxm
// @match https://seiga.nicovideo.jp/tag/*
// @match https://seiga.nicovideo.jp/seiga/*
// @match https://seiga.nicovideo.jp/my/personalize*
// @connect seiga.nicovideo.jp
// @grant GM.xmlHttpRequest
// @grant GM.getValue
// @grant GM.setValue
// @run-at document-start
// ==/UserScript==
(async () => {
"use strict";
;
;
class Util {
//xmlString=未探査部分
static XmlToObj(xmlString) {
const F = (xmlString, obj) => {
//タグを抜き出す
let tagMatchs = null;
while (true) {
tagMatchs = xmlString.match(/<([^>]+)>/);
//タグがないということはそれが値になる
if (tagMatchs == null) {
return xmlString;
}
if (tagMatchs[1][tagMatchs[1].length - 1] == "/") {
xmlString = xmlString.replace(/<[^>]+>([^]*)/, "$1");
}
else {
break;
}
}
const tag = tagMatchs[1];
//タグの内側とその先を抜き出す
const matchChildlen = [];
while (true) {
const matchs = xmlString.match(new RegExp(`^[^<]*<${tag}>([^]+?)<\/${tag}>([^]*)`));
if (matchs == null) {
break;
}
matchChildlen.push(matchs[1]);
xmlString = matchs[2];
}
//タグあったのにマッチしなかったおかしい
if (matchChildlen.length == 0) {
return obj;
}
//そのタグが一つしかないとき、オブジェクトになる
if (matchChildlen.length == 1) {
//子を探す
obj[tag] = F(matchChildlen[0], {});
}
//そのタグが複数あるとき、配列になる
if (matchChildlen.length > 1) {
obj = [];
for (let i = 0; i < matchChildlen.length; i++) {
//子を探す
obj[i] = F(matchChildlen[i], {});
}
}
//兄弟を探す
F(xmlString, obj);
return obj;
};
//初期化で<xml>を取り除く
xmlString = xmlString.replace(/\s*<[^>]+>([^]+)/, "$1");
return F(xmlString, {});
}
static HtmlToDocument(str) {
const parser = new DOMParser();
return parser.parseFromString(str, "text/html");
}
static HtmlToChildNodes(str) {
return this.HtmlToDocument(str).body.childNodes;
}
static Wait(ms) {
return new Promise(r => setTimeout(r, ms));
}
static async Download(url, name) {
const link = document.createElement("a");
document.body.appendChild(link);
link.download = name;
link.href = url;
link.click();
//すぐに消すと反応しないとか
await this.Wait(100);
document.body.removeChild(link);
}
}
;
class Fetcher {
static GMFetchText(url) {
return new Promise(r => {
GM.xmlHttpRequest({
url: url,
method: "GET",
onload: (response) => {
r(response.responseText);
}
});
});
}
static async FetchIllustDatas(ids) {
if (ids.length == 0) {
return { illusts: [], userIds: [] };
}
const url = `http:\/\/seiga.nicovideo.jp/api/illust/info?id_list=${ids.join()}`;
const res = await this.GMFetchText(url);
const obj = Util.XmlToObj(res);
const list = Array.isArray(obj.response.image_list) ? obj.response.image_list : [obj.response.image_list.image];
const illusts = [];
for (let i = 0; i < list.length; i++) {
illusts[i] = {
id: list[i].id,
created: new Date(list[i].created)
};
}
return {
illusts: illusts,
userIds: list.map(l => l.user_id)
};
}
static async FetchUserName(userId) {
const url = "http://seiga.nicovideo.jp/api/user/info?id=" + userId;
const json = Util.XmlToObj(await this.GMFetchText(url));
return json.response.user.nickname;
}
static async FetchUserId(illustId) {
const url = "https://seiga.nicovideo.jp/api/illust/info?id=im" + illustId;
const resultText = await this.GMFetchText(url);
const json = Util.XmlToObj(resultText);
return json.response.image.user_id;
}
}
;
class Storage {
constructor(storageName) {
this.storageName = "";
this.storageName = storageName;
}
async GetStorageData(defaultValue = null) {
const text = await GM.getValue(this.storageName, null);
return text != null ? JSON.parse(decodeURIComponent(text)) : defaultValue;
}
async SetStorageData(data) {
await GM.setValue(this.storageName, encodeURIComponent(JSON.stringify(data)));
}
}
;
class Observer {
static Wait(predicate, parent = document, option = null) {
return new Promise(r => {
if (option == null) {
option = {
childList: true,
subtree: true
};
}
const mutationObserver = new MutationObserver((mrs) => {
if (predicate(mrs)) {
mutationObserver.disconnect();
r(mrs);
return;
}
});
mutationObserver.observe(parent, option);
});
}
;
static WaitAddedNode(predicate, parent, option = null) {
return new Promise(r => {
if (option == null) {
option = {
childList: true,
subtree: true
};
}
const mutationObserver = new MutationObserver((mrs) => {
//console.log(document.head.innerHTML);
//console.log(document.body.innerHTML);
for (let node of mrs) {
node.addedNodes.forEach(added => {
//console.log(added);
if (predicate(added)) {
mutationObserver.disconnect();
r(added);
return;
}
});
}
});
mutationObserver.observe(parent, option);
});
}
;
static async DefinitelyGetElementById(id, parent = document, option = null) {
const e = document.getElementById(id);
if (e != null) {
return e;
}
return this.WaitAddedNode(e => e.id != null && e.id == id, parent, option);
}
//getElementsByClassNameをつかうけど単体なので注意
static async DefinitelyGetElementByClassName(className, parent = document, option = null) {
const e = document.getElementsByClassName(className)[0];
if (e != null) {
return e;
}
return this.WaitAddedNode(e => e.classList != null && e.classList.contains(className), parent, option);
}
//getElementsByTagNameをつかうけど単体なので注意
static async DefinitelyGetElementByTagName(tagName, parent = document, option = null) {
tagName = tagName.toUpperCase();
const e = document.getElementsByTagName(tagName)[0];
if (e != null) {
return e;
}
return this.WaitAddedNode(e => e.tagName != null && e.tagName == tagName, parent, option);
}
}
;
//暫定OK、暫定荒らし、確定OK、確定荒らし
//type Status = "OK" | "NG" | "LOK" | "LNG"
let PageType;
(function (PageType) {
PageType[PageType["None"] = -1] = "None";
PageType[PageType["TAG_SEARCH"] = 0] = "TAG_SEARCH";
PageType[PageType["ILLUST"] = 1] = "ILLUST";
PageType[PageType["PERSONALIZE"] = 2] = "PERSONALIZE";
PageType[PageType["MAX"] = 3] = "MAX";
})(PageType || (PageType = {}));
;
;
const pageInfos = [
{
regex: /https:\/\/seiga.nicovideo.jp\/tag\/.*/,
name: "タグ検索",
illustListName: "item_list",
illustItemName: "list_item",
},
{
regex: /https:\/\/seiga.nicovideo.jp\/seiga\/.*/,
name: "イラストページ",
illustListName: "item_list",
illustItemName: "list_item_cutout",
},
{
regex: /https:\/\/seiga.nicovideo.jp\/my\/personalize.*/,
name: "定点観測",
illustListName: "list_body",
illustItemName: "illust_thumb",
}
];
let Status;
(function (Status) {
Status[Status["NONE"] = 0] = "NONE";
Status[Status["OK"] = 1] = "OK";
Status[Status["NG"] = 2] = "NG";
Status[Status["WHITE"] = 3] = "WHITE";
Status[Status["BLACK"] = 4] = "BLACK";
Status[Status["MAX"] = 5] = "MAX";
})(Status || (Status = {}));
class Main {
constructor() {
this.cache = [];
this.illustInfos = [];
this.illustListElements = new Set();
this.selectedList = [];
this.cacheStorage = new Storage("NICONICO_RENTO_ARASI_NG_DATA_CACHE");
this.optionStorage = new Storage("NICONICO_RENTO_ARASI_NG_OPTION_CACHE");
this.imgIntersectionObserver = new IntersectionObserver(entries => {
for (let e of entries) {
if (e.intersectionRatio > 0) {
const img = e.target;
if (img.src != null && img.dataset != null && img.dataset.src != null) {
img.src = img.dataset.src;
}
this.imgIntersectionObserver.unobserve(img);
}
}
});
}
async GetStorageData() {
this.cache = (await this.cacheStorage.GetStorageData([]));
//console.log(this.cache);
const defaultOption = {
usePages: [true, false, false],
judge: {
isJudge: false,
time: 1 * 60 * 60 * 1000,
postCount: 3
},
createUserLink: true,
createBlackWhiteButton: true,
okCacheMax: 1000,
};
this.option = await this.optionStorage.GetStorageData(defaultOption);
if (this.option.usePages == undefined) {
this.option.usePages = defaultOption.usePages;
}
for (let i = 0; i < PageType.MAX; i++) {
if (this.option.usePages[i] == undefined) {
this.option.usePages[i] = defaultOption.usePages[i];
}
}
if (this.option.judge == undefined) {
this.option.judge = defaultOption.judge;
}
if (this.option.judge.time == undefined) {
this.option.judge.time = defaultOption.judge.time;
}
if (this.option.judge.postCount == undefined) {
this.option.judge.postCount = defaultOption.judge.postCount;
}
if (this.option.judge.isJudge == undefined) {
this.option.judge.isJudge = defaultOption.judge.isJudge;
}
if (this.option.createUserLink == undefined) {
this.option.createUserLink = defaultOption.createUserLink;
}
if (this.option.createBlackWhiteButton == undefined) {
this.option.createBlackWhiteButton = defaultOption.createBlackWhiteButton;
}
if (this.option.okCacheMax == undefined) {
this.option.okCacheMax = defaultOption.okCacheMax;
}
//console.log(this.option);
}
GetInfo(illustId) {
for (let c of this.cache) {
for (let illust of c.illusts) {
if (illust.id == illustId) {
return { user: c, illust: illust };
}
}
}
return undefined;
}
CheckArasi(user) {
if (user.illusts.length == 0 || user.status == Status.BLACK || user.status == Status.WHITE || user.status == Status.NG) {
return;
}
for (let illust of user.illusts) {
if (typeof illust.created == "string") {
illust.created = new Date(illust.created);
}
}
//新しい順
const sorted = user.illusts.sort((a, b) => b.created.getTime() - a.created.getTime());
for (let i = 0; i < sorted.length; i++) {
const currentDate = sorted[i].created;
let j = i + 1;
let postCount = 1;
while (true) {
if (j >= sorted.length || currentDate.getTime() - sorted[j].created.getTime() > this.option.judge.time) {
break;
}
j++;
postCount++;
}
if (postCount >= this.option.judge.postCount) {
user.status = Status.NG;
return;
}
}
}
;
GetIllustIds(itemListElement) {
var _a;
const illustIdElements = itemListElement.getElementsByTagName("a");
const illustIds = new Set();
for (let i = 0; i < illustIdElements.length; i++) {
if (illustIdElements[i].parentElement != null && ((_a = illustIdElements[i].parentElement) === null || _a === void 0 ? void 0 : _a.classList.contains("list_more_link"))) {
continue;
}
const idMatchs = illustIdElements[i].href.match(/im(\d+)/);
if (idMatchs == null) {
continue;
}
const id = idMatchs[1];
illustIds.add(id);
}
return [...illustIds];
}
DrawList() {
const list = this.optionDialog.getElementsByClassName("scrollUL")[0];
const onlyCurrentPageCheckbox = this.optionDialog.getElementsByClassName("onlyCurrentPageCheckbox")[0];
const listStatusSelect = this.optionDialog.getElementsByClassName("listStatusSelect")[0];
if (list == undefined || onlyCurrentPageCheckbox == undefined || listStatusSelect == undefined) {
return;
}
const status = listStatusSelect.value == "ALL" ? "" : Status[listStatusSelect.value];
list.innerHTML = "";
for (let user of this.cache) {
if (status != "" && user.status != status) {
continue;
}
const info = this.illustInfos.find(info => info.user.userId == user.userId);
let sampleIllustId = info != undefined ? info.illustId : undefined;
if (onlyCurrentPageCheckbox.checked && sampleIllustId == undefined) {
continue;
}
if (sampleIllustId == undefined) {
sampleIllustId = user.illusts[0].id;
}
const div = document.createElement("div");
div.style.height = "70px";
div.style.display = "flex";
div.style.flexDirection = "column";
div.className = "userInfoItem";
list.appendChild(div);
div.addEventListener("mouseup", e => this.ClickList(div));
{
const nameIdDiv = document.createElement("div");
nameIdDiv.style.top = "relative";
nameIdDiv.style.position = "4px";
div.appendChild(nameIdDiv);
{
const nameSpan = document.createElement("span");
nameSpan.className = "userName";
nameSpan.textContent = info == undefined ? "" : info.name;
nameSpan.style.fontSize = "130%";
nameSpan.style.color = "black";
nameSpan.style.width = "66px";
nameSpan.style.height = "24px";
nameSpan.style.padding = "3px";
nameIdDiv.appendChild(nameSpan);
const idSpan = document.createElement("span");
idSpan.className = "userId";
idSpan.textContent = user.userId;
idSpan.style.fontSize = "130%";
idSpan.style.color = "black";
idSpan.style.width = "66px";
idSpan.style.padding = "3px";
nameIdDiv.appendChild(idSpan);
}
const userAndSampleImgDiv = document.createElement("div");
div.appendChild(userAndSampleImgDiv);
{
const aUser = document.createElement("a");
aUser.href = `https:\/\/seiga.nicovideo.jp/user/illust/${user.userId}`;
userAndSampleImgDiv.appendChild(aUser);
{
const imgUser = document.createElement("img");
imgUser.dataset.src = `https:\/\/secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/${Math.floor(parseInt(user.userId) / 10000)}/${user.userId}.jpg`;
imgUser.style.height = "40px";
imgUser.style.position = "relative";
imgUser.style.padding = "0 20px 0 10px";
imgUser.style.top = "-5px";
this.imgIntersectionObserver.observe(imgUser);
aUser.appendChild(imgUser);
imgUser.addEventListener("error", () => {
imgUser.src = "https:\/\/secure-dcdn.cdn.nimg.jp/nicoaccount/usericon/defaults/blank.jpg";
});
}
const aSample = document.createElement("a");
aSample.href = `https:/\/seiga.nicovideo.jp/seiga/im${sampleIllustId}`;
userAndSampleImgDiv.appendChild(aSample);
{
const imgSample = document.createElement("img");
imgSample.dataset.src = `https:\/\/lohas.nicoseiga.jp\/\/thumb/${sampleIllustId}c`;
imgSample.style.height = "30px";
this.imgIntersectionObserver.observe(imgSample);
imgSample.style.position = "relative";
imgSample.style.top = "-5px";
aSample.appendChild(imgSample);
const bigSample = document.createElement("img");
bigSample.dataset.src = `https:\/\/lohas.nicoseiga.jp\/\/thumb/${sampleIllustId}c`;
bigSample.style.height = "100px";
this.imgIntersectionObserver.observe(bigSample);
bigSample.style.pointerEvents = "none";
bigSample.style.position = "absolute";
bigSample.style.zIndex = "110";
imgSample.addEventListener("mouseover", () => {
const clientRect = imgSample.getBoundingClientRect();
const x = window.pageXOffset + clientRect.left + imgSample.width / 2 - 50;
const y = window.pageYOffset + clientRect.top + imgSample.height / 2 - 50;
bigSample.style.top = y + "px";
bigSample.style.left = x + "px";
document.body.appendChild(bigSample);
});
imgSample.addEventListener("mouseleave", () => {
bigSample.remove();
});
}
}
}
}
}
ClickList(target) {
if (target != null) {
if (this.selectedList.includes(target)) {
target.style.backgroundColor = "";
this.selectedList = this.selectedList.filter(s => s != target);
}
else {
target.style.backgroundColor = "rgba(0, 140, 255, 0.5)";
this.selectedList.push(target);
}
}
}
async SetOptionButton() {
const parent = await Observer.DefinitelyGetElementByClassName("sg_pankuzu");
if (document.getElementById("optionSpan") != null) {
return;
}
const optionSpan = document.createElement("span");
optionSpan.id = "optionSpan";
optionSpan.style.margin = "0 10px";
parent.appendChild(optionSpan);
{
const optionButton = document.createElement("input");
optionButton.type = "button";
optionButton.value = "簡単NGスクリプト";
optionButton.style.backgroundColor = "yellow";
optionButton.style.padding = "1px 10px";
optionButton.style.fontSize = "110%";
optionButton.style.cssText += "color: black !important;";
optionButton.addEventListener("click", () => {
if (this.optionDialog.parentElement == null) {
optionSpan.appendChild(this.optionDialog);
return;
}
this.optionDialog.style.display = (this.optionDialog.style.display == "none") ? "block" : "none";
});
optionSpan.appendChild(optionButton);
this.optionDialog = document.createElement("div");
this.optionDialog.style.backgroundColor = "white";
this.optionDialog.style.position = "absolute";
this.optionDialog.style.padding = "5px";
this.optionDialog.style.marginLeft = "10px";
this.optionDialog.style.zIndex = "100";
this.optionDialog.style.border = "2px solid";
{
const list1 = document.createElement("div");
list1.style.display = "flex";
list1.style.paddingTop = "5px";
list1.style.paddingBottom = "10px";
this.optionDialog.appendChild(list1);
{
const listStatusSelect = document.createElement("select");
listStatusSelect.className = "listStatusSelect";
listStatusSelect.style.margin = "5px";
list1.appendChild(listStatusSelect);
for (let i = 1; i <= Status.MAX; i++) {
const option = document.createElement("option");
const text = i == Status.MAX ? "ALL" : Status[i];
option.value = text;
option.textContent = text;
listStatusSelect.appendChild(option);
}
listStatusSelect.addEventListener("change", () => {
while (this.selectedList.length != 0) {
const element = this.selectedList.pop();
if (element != undefined) {
element.style.backgroundColor = "";
}
}
this.DrawList();
});
const onlyCurrentPageLabel = document.createElement("label");
onlyCurrentPageLabel.style.color = "black";
onlyCurrentPageLabel.style.padding = "3px";
onlyCurrentPageLabel.style.display = "flex";
list1.appendChild(onlyCurrentPageLabel);
{
const onlyCurrentPageCheckbox = document.createElement("input");
onlyCurrentPageCheckbox.type = "checkbox";
onlyCurrentPageCheckbox.className = "onlyCurrentPageCheckbox";
onlyCurrentPageCheckbox.checked = true;
onlyCurrentPageCheckbox.style.padding = "3px";
onlyCurrentPageCheckbox.style.margin = "10px";
onlyCurrentPageCheckbox.style.marginRight = "3px";
onlyCurrentPageCheckbox.style.marginLeft = "0px";
onlyCurrentPageLabel.appendChild(onlyCurrentPageCheckbox);
onlyCurrentPageCheckbox.addEventListener("change", () => this.DrawList());
const onlyCurrentPageText = document.createElement("div");
onlyCurrentPageText.textContent = "このページだけ";
onlyCurrentPageText.style.color = "black";
onlyCurrentPageLabel.appendChild(onlyCurrentPageText);
}
const allSelect = document.createElement("input");
allSelect.type = "button";
allSelect.value = "全選択";
allSelect.style.color = "black";
allSelect.style.fontSize = "120%";
allSelect.style.padding = "0 5px";
allSelect.style.margin = "3px";
list1.appendChild(allSelect);
allSelect.addEventListener("click", () => {
const infos = Array.from(document.getElementsByClassName("userInfoItem"));
for (let info of infos) {
this.ClickList(info);
}
});
const detailButton = document.createElement("input");
detailButton.type = "button";
detailButton.value = "設定";
detailButton.style.color = "black";
detailButton.style.fontSize = "120%";
detailButton.style.margin = "3px";
detailButton.style.marginLeft = "45px";
detailButton.style.padding = "0 10px";
list1.appendChild(detailButton);
detailButton.addEventListener("click", () => detailDialog.style.display = (detailDialog.style.display == "none") ? "block" : "none");
const detailDialog = document.createElement("div");
detailDialog.style.backgroundColor = "white";
detailDialog.style.display = "none";
detailDialog.style.position = "absolute";
detailDialog.style.padding = "0 10px";
detailDialog.style.zIndex = "100";
detailDialog.style.border = "2px solid";
detailDialog.style.left = "360px";
detailDialog.style.top = "10px";
list1.appendChild(detailDialog);
const useSettingH3 = document.createElement("h1");
useSettingH3.textContent = "使うところ";
useSettingH3.style.fontSize = "140%";
useSettingH3.style.marginTop = "10px";
useSettingH3.style.color = "black";
detailDialog.appendChild(useSettingH3);
const setUseListDiv = document.createElement("div");
setUseListDiv.style.marginBottom = "10px";
detailDialog.appendChild(setUseListDiv);
{
for (let i = 0; i < PageType.MAX; i++) {
const setUseLabel = document.createElement("label");
setUseLabel.style.display = "flex";
setUseListDiv.appendChild(setUseLabel);
{
const setUsePageCheckbox = document.createElement("input");
setUsePageCheckbox.type = "checkbox";
setUsePageCheckbox.checked = this.option.usePages[i];
setUsePageCheckbox.style.padding = "3px";
setUsePageCheckbox.style.margin = "10px";
setUsePageCheckbox.style.marginRight = "3px";
setUseLabel.appendChild(setUsePageCheckbox);
setUsePageCheckbox.addEventListener("change", async () => {
this.option.usePages[i] = setUsePageCheckbox.checked;
await this.optionStorage.SetStorageData(this.option);
});
const setUsePageText = document.createElement("div");
setUsePageText.textContent = pageInfos[i].name;
setUsePageText.style.padding = "3px";
setUsePageText.style.fontSize = "120%";
setUsePageText.style.color = "black";
setUseLabel.appendChild(setUsePageText);
}
}
}
const otherSettingH3 = document.createElement("h1");
otherSettingH3.textContent = "イラストサムネ";
otherSettingH3.style.fontSize = "140%";
otherSettingH3.style.marginTop = "10px";
otherSettingH3.style.color = "black";
detailDialog.appendChild(otherSettingH3);
const setCreateUserLinkDiv = document.createElement("div");
setCreateUserLinkDiv.style.display = "flex";
detailDialog.appendChild(setCreateUserLinkDiv);
{
const setCreateUserLinkChackbox = document.createElement("input");
setCreateUserLinkChackbox.type = "checkbox";
setCreateUserLinkChackbox.id = "createUserLink";
setCreateUserLinkChackbox.checked = this.option.createUserLink;
setCreateUserLinkChackbox.style.padding = "3px";
setCreateUserLinkChackbox.style.margin = "10px";
setCreateUserLinkChackbox.style.marginRight = "3px";
setCreateUserLinkDiv.appendChild(setCreateUserLinkChackbox);
setCreateUserLinkChackbox.addEventListener("change", async () => {
this.option.createUserLink = setCreateUserLinkChackbox.checked;
await this.optionStorage.SetStorageData(this.option);
});
const setCreateUserLinkDivLabel = document.createElement("label");
setCreateUserLinkDivLabel.htmlFor = "createUserLink";
setCreateUserLinkDivLabel.textContent = "ユーザー名をユーザーページへのリンクにする";
setCreateUserLinkDivLabel.style.color = "black";
setCreateUserLinkDivLabel.style.padding = "3px";
setCreateUserLinkDivLabel.style.fontSize = "120%";
setCreateUserLinkDiv.appendChild(setCreateUserLinkDivLabel);
}
const setCreateBlackWhiteButtonDiv = document.createElement("div");
setCreateBlackWhiteButtonDiv.style.display = "flex";
detailDialog.appendChild(setCreateBlackWhiteButtonDiv);
{
const setCreateBlackWhiteButtonChackbox = document.createElement("input");
setCreateBlackWhiteButtonChackbox.type = "checkbox";
setCreateBlackWhiteButtonChackbox.id = "setCreateBlackWhiteButton";
setCreateBlackWhiteButtonChackbox.checked = this.option.createBlackWhiteButton;
setCreateBlackWhiteButtonChackbox.style.padding = "3px";
setCreateBlackWhiteButtonChackbox.style.margin = "10px";
setCreateBlackWhiteButtonChackbox.style.marginRight = "3px";
setCreateBlackWhiteButtonDiv.appendChild(setCreateBlackWhiteButtonChackbox);
setCreateBlackWhiteButtonChackbox.addEventListener("change", async () => {
this.option.createBlackWhiteButton = setCreateBlackWhiteButtonChackbox.checked;
await this.optionStorage.SetStorageData(this.option);
});
const setCreateBlackWhiteButtonLabel = document.createElement("label");
setCreateBlackWhiteButtonLabel.htmlFor = "setCreateBlackWhiteButton";
setCreateBlackWhiteButtonLabel.textContent = "白黒ボタンを付ける";
setCreateBlackWhiteButtonLabel.style.color = "black";
setCreateBlackWhiteButtonLabel.style.padding = "3px";
setCreateBlackWhiteButtonLabel.style.fontSize = "120%";
setCreateBlackWhiteButtonDiv.appendChild(setCreateBlackWhiteButtonLabel);
}
const otherSettingH4 = document.createElement("h1");
otherSettingH4.textContent = "その他";
otherSettingH4.style.fontSize = "140%";
otherSettingH4.style.marginTop = "10px";
otherSettingH4.style.color = "black";
detailDialog.appendChild(otherSettingH4);
const judgeRigorCover = document.createElement("div");
const setIsJudgeDiv = document.createElement("div");
setIsJudgeDiv.style.display = "flex";
detailDialog.appendChild(setIsJudgeDiv);
{
const isJudgeCheckbox = document.createElement("input");
isJudgeCheckbox.type = "checkbox";
isJudgeCheckbox.id = "isJudgeCheckbox";
isJudgeCheckbox.checked = this.option.judge.isJudge;
isJudgeCheckbox.style.padding = "3px";
isJudgeCheckbox.style.margin = "10px";
isJudgeCheckbox.style.marginRight = "3px";
setIsJudgeDiv.appendChild(isJudgeCheckbox);
isJudgeCheckbox.addEventListener("change", async () => {
this.option.judge.isJudge = isJudgeCheckbox.checked;
if (this.option.judge.isJudge) {
judgeRigorCover.style.visibility = "hidden";
}
else {
judgeRigorCover.style.visibility = "visible";
}
await this.optionStorage.SetStorageData(this.option);
});
const isJudgeLabel = document.createElement("label");
isJudgeLabel.htmlFor = "isJudgeCheckbox";
isJudgeLabel.textContent = "連投自動NG";
isJudgeLabel.style.color = "black";
isJudgeLabel.style.padding = "3px";
isJudgeLabel.style.fontSize = "120%";
setIsJudgeDiv.appendChild(isJudgeLabel);
}
const setJudgeRigorFlex = document.createElement("div");
setJudgeRigorFlex.style.padding = "0px 10px 5px 10px";
setJudgeRigorFlex.style.position = "relative";
detailDialog.appendChild(setJudgeRigorFlex);
{
const setJudgeTime = document.createElement("input");
setJudgeTime.type = "time";
setJudgeTime.style.height = "20px";
setJudgeTime.style.fontSize = "120%";
const hour = ('00' + Math.floor(this.option.judge.time / 60 / 1000 / 60).toString()).slice(-2);
const minutes = ('00' + (this.option.judge.time / 60 / 1000 % 60).toString()).slice(-2);
setJudgeTime.value = `${hour}:${minutes}`;
setJudgeTime.addEventListener("change", async () => {
const [h, m] = setJudgeTime.value.split(":").map(s => parseInt(s));
const ms = ((h * 60) + m) * 60 * 1000;
if (ms >= 1) {
this.option.judge.time = ms;
await this.optionStorage.SetStorageData(this.option);
}
else {
const hour = ('00' + Math.floor(this.option.judge.time / 60 / 1000 / 60).toString()).slice(-2);
const minutes = ('00' + (this.option.judge.time / 60 / 1000 % 60).toString()).slice(-2);
setJudgeTime.value = `${hour}:${minutes}`;
}
});
setJudgeRigorFlex.appendChild(setJudgeTime);
const setJudgeText1 = document.createElement("span");
setJudgeText1.textContent = "以内に";
setJudgeText1.style.color = "black";
setJudgeText1.style.fontSize = "15px";
setJudgeRigorFlex.appendChild(setJudgeText1);
const setJudgePostCount = document.createElement("input");
setJudgePostCount.type = "number";
setJudgePostCount.value = this.option.judge.postCount.toString();
setJudgePostCount.style.width = "40px";
setJudgePostCount.min = "2";
setJudgePostCount.style.height = "20px";
setJudgePostCount.style.fontSize = "120%";
setJudgePostCount.addEventListener("change", async () => {
const num = parseInt(setJudgePostCount.value);
if (num >= 2) {
this.option.judge.postCount = num;
await this.optionStorage.SetStorageData(this.option);
}
else {
this.option.judge.postCount = 2;
setJudgePostCount.value = this.option.judge.postCount.toString();
}
});
setJudgeRigorFlex.appendChild(setJudgePostCount);
const setJudgeText2 = document.createElement("span");
setJudgeText2.textContent = "回投稿で仮荒らし認定";
setJudgeText2.style.color = "black";
setJudgeText2.style.fontSize = "15px";
setJudgeRigorFlex.appendChild(setJudgeText2);
judgeRigorCover.style.backgroundColor = "gray";
judgeRigorCover.style.width = "310px";
judgeRigorCover.style.height = "30px";
judgeRigorCover.style.zIndex = "1000";
judgeRigorCover.style.opacity = "0.5";
judgeRigorCover.style.position = "absolute";
judgeRigorCover.style.top = "0";
setJudgeRigorFlex.appendChild(judgeRigorCover);
if (this.option.judge.isJudge) {
judgeRigorCover.style.visibility = "hidden";
}
else {
judgeRigorCover.style.visibility = "visible";
}
}
const categoryBlock3 = document.createElement("div");
categoryBlock3.style.margin = "10px 0";
detailDialog.appendChild(categoryBlock3);
const setOKCacheMaxFlex = document.createElement("div");
setOKCacheMaxFlex.style.padding = "5px";
detailDialog.appendChild(setOKCacheMaxFlex);
{
const setOKCacheMaxText1 = document.createElement("span");
setOKCacheMaxText1.textContent = "OKユーザーのキャッシュ最大数:";
setOKCacheMaxText1.style.color = "black";
setOKCacheMaxText1.style.fontSize = "15px";
setOKCacheMaxFlex.appendChild(setOKCacheMaxText1);
const setOKCacheMax = document.createElement("input");
setOKCacheMax.type = "number";
setOKCacheMax.value = this.option.okCacheMax.toString();
setOKCacheMax.style.width = "80px";
setOKCacheMax.min = "100";
setOKCacheMax.style.height = "20px";
setOKCacheMax.style.fontSize = "120%";
setOKCacheMax.addEventListener("change", async () => {
const num = parseInt(setOKCacheMax.value);
if (num >= 100) {
this.option.okCacheMax = num;
await this.optionStorage.SetStorageData(this.option);
}
else {
this.option.okCacheMax = 100;
setOKCacheMax.value = this.option.okCacheMax.toString();
}
});
setOKCacheMaxFlex.appendChild(setOKCacheMax);
}
}
const list2 = document.createElement("div");
list2.style.position = "relative";
list2.style.display = "flex";
this.optionDialog.appendChild(list2);
{
const userInfoList = document.createElement("ul");
userInfoList.className = "scrollUL";
userInfoList.style.overflowY = "scroll";
userInfoList.style.overflowX = "hidden";
userInfoList.style.height = "380px";
userInfoList.style.width = "250px";
list2.appendChild(userInfoList);
const buttonList = document.createElement("ul");
buttonList.style.width = "90px";
list2.appendChild(buttonList);
{
const moveButtonList = document.createElement("div");
moveButtonList.style.marginTop = "20px";
moveButtonList.style.marginBottom = "10px";
buttonList.appendChild(moveButtonList);
{
for (let i = 1; i < Status.MAX; i++) {
const div = document.createElement("div");
moveButtonList.appendChild(div);
{
const toButton = document.createElement("input");
toButton.type = "button";
toButton.style.padding = "3px";
toButton.style.fontSize = "130%";
toButton.style.margin = "3px";
toButton.value = "→ " + Status[i];
toButton.name = Status[i];
div.appendChild(toButton);
toButton.addEventListener("click", async () => {
while (this.selectedList.length != 0) {
const element = this.selectedList.pop();
if (element == undefined) {
continue;
}
element.style.backgroundColor = "";
const userId = element.getElementsByClassName("userId")[0].textContent;
const user = this.cache.find(c => c.userId == userId);
if (user != undefined) {
user.status = Status[toButton.name];
}
}
for (let info of this.illustInfos) {
this.UpdateIllust(info);
this.DrawBlackWhiteButton(info);
}
this.UpdateIllustList();
this.DrawList();
await this.cacheStorage.SetStorageData(this.cache);
});
}
}
}
const DeleteSelectedUser = () => {
while (this.selectedList.length != 0) {
const element = this.selectedList.pop();
if (element == undefined) {
continue;
}
const userId = element.getElementsByClassName("userId")[0].textContent;
this.cache = this.cache.filter(c => c.userId != userId);
const infos = this.illustInfos.filter(c => c.user.userId == userId);
for (let info of infos) {
info.user.status = Status.WHITE;
this.UpdateIllust(info);
this.DrawBlackWhiteButton(info);
}
this.UpdateIllustList();
this.illustInfos = this.illustInfos.filter(c => c.user.userId != userId);
}
};
const div = document.createElement("div");
buttonList.appendChild(div);
{
const selectedCacheClearButton = document.createElement("input");
selectedCacheClearButton.type = "button";
selectedCacheClearButton.style.padding = "3px";
selectedCacheClearButton.style.fontSize = "120%";
selectedCacheClearButton.style.margin = "3px";
selectedCacheClearButton.style.marginTop = "5px";
selectedCacheClearButton.style.backgroundColor = "yellow";
selectedCacheClearButton.style.cssText += "color: black !important";
selectedCacheClearButton.value = "→ DELETE";
div.appendChild(selectedCacheClearButton);
selectedCacheClearButton.addEventListener("click", async () => {
if (!window.confirm("選択したアイテムのキャッシュクリアしていいですか?\nホワイト・ブラックリストも削除されます。")) {
return;
}
DeleteSelectedUser();
this.DrawList();
await this.cacheStorage.SetStorageData(this.cache);
});
}
const div2 = document.createElement("div");
buttonList.appendChild(div2);
{
const allCacheClearButton = document.createElement("input");
allCacheClearButton.type = "button";
allCacheClearButton.style.padding = "3px";
allCacheClearButton.style.fontSize = "120%";
allCacheClearButton.style.margin = "3px";
allCacheClearButton.style.backgroundColor = "red";
allCacheClearButton.value = "ALL DELETE";
div2.appendChild(allCacheClearButton);
allCacheClearButton.addEventListener("click", async () => {
if (!window.confirm("全キャッシュクリアしていいですか?\nホワイト・ブラックリストも削除されます。")) {
return;
}
for (let info of this.illustInfos) {
info.user.status = Status.WHITE;
this.UpdateIllust(info);
this.DrawBlackWhiteButton(info);
}
this.illustInfos = [];
this.UpdateIllustList();
this.cache = [];
this.DrawList();
await this.cacheStorage.SetStorageData(this.cache);
});
}
const div3 = document.createElement("div");
buttonList.appendChild(div3);
{
const reStartButton = document.createElement("input");
reStartButton.type = "button";
reStartButton.style.padding = "3px";
reStartButton.style.fontSize = "120%";
reStartButton.style.margin = "3px";
reStartButton.style.marginTop = "10px";
reStartButton.style.backgroundColor = "green";
reStartButton.style.cssText += "color: white !important";
reStartButton.value = "RE START";
div3.appendChild(reStartButton);
reStartButton.addEventListener("click", async () => {
await this.Run();
});
}
const div4 = document.createElement("div");
div4.style.marginTop = "10px";
div4.style.marginBottom = "10px";
buttonList.appendChild(div4);
{
const importDiv = document.createElement("div");
importDiv.style.position = "relative";
div4.appendChild(importDiv);
{
const importButton = document.createElement("input");
importButton.type = "button";
importButton.style.padding = "3px";
importButton.style.fontSize = "120%";
importButton.style.margin = "3px";
importButton.style.marginTop = "10px";
importButton.value = "← IMPORT";
importDiv.appendChild(importButton);
const importFile = document.createElement("input");
importFile.type = "file";
importFile.style.position = "absolute";
importFile.style.opacity = "0";
importFile.style.width = "80px";
importFile.style.top = "8px";
importFile.style.left = "0";
importFile.accept = "text/plain";
importFile.style.padding = "0";
importDiv.appendChild(importFile);
importFile.addEventListener("change", async (e) => {
if (e.target == null) {
return;
}
const files = e.target.files;
if (files == null) {
return;
}
const file = files[0];
if (file.type != "text/plain") {
alert("テキストファイルを入れてください。");
return;
}
if (!window.confirm("インポートしていいですか?\nインポートする前に、今選択しているユーザーは削除されます。")) {
return;
}
DeleteSelectedUser();
this.DrawList();
const reader = new FileReader();
reader.readAsText(file);
reader.onload = async () => {
if (typeof reader.result != "string") {
return;
}
const importUsers = JSON.parse(reader.result);
for (let imUser of importUsers) {
for (let illust of imUser.illusts) {
illust.created = new Date(illust.created);
}
}
for (let imUser of importUsers) {
const cachedUser = this.cache.find(c => c.userId == imUser.userId);
if (cachedUser == undefined) {
this.cache.push(imUser);
}
else {
cachedUser.status = imUser.status;
for (let illust of cachedUser.illusts) {
if (cachedUser.illusts.some(c => c.id == illust.id)) {
continue;
}
cachedUser.illusts.push(illust);
}
}
}
await this.cacheStorage.SetStorageData(this.cache);
this.Run();
};
});
}
const exportEiv = document.createElement("div");
div4.appendChild(exportEiv);
{
const reStartButton = document.createElement("input");
reStartButton.type = "button";
reStartButton.style.padding = "3px";
reStartButton.style.fontSize = "120%";
reStartButton.style.margin = "3px";
reStartButton.style.marginTop = "5px";
reStartButton.value = "→ EXPORT";
exportEiv.appendChild(reStartButton);
reStartButton.addEventListener("click", async () => {
const selectedUsers = [];
for (let element of this.selectedList) {
if (element == undefined) {
continue;
}
const userId = element.getElementsByClassName("userId")[0].textContent;
const user = this.cache.find(c => c.userId == userId);
if (user != undefined) {
selectedUsers.push(user);
}
}
if (selectedUsers.length == 0) {
alert("出力するユーザーを選択してください");
return;
}
const listStatusSelect = this.optionDialog.getElementsByClassName("listStatusSelect")[0];
const status = listStatusSelect.value;
const blob = new Blob([JSON.stringify(selectedUsers)], { type: "text/plain" });
const dlUrl = URL.createObjectURL(blob);
await Util.Download(dlUrl, `niconicoNG_${status}.txt`);
});
}
}
}
}
}
}
}
UpdateIllust(info) {
if (info.user.status == Status.OK || info.user.status == Status.WHITE) {
info.element.getElementsByTagName("img")[0].style.filter = "brightness(1)";
if (info.element.parentElement == null) {
info.parent.appendChild(info.element);
}
}
if (info.user.status == Status.NG) {
info.element.getElementsByTagName("img")[0].style.filter = "brightness(0.3)";
info.parent.appendChild(info.element);
}
if (info.user.status == Status.BLACK) {
info.element.remove();
}
}
UpdateIllustList() {
for (let illustListElement of this.illustListElements) {
if (this.currentPage == PageType.ILLUST) {
for (let moreLink of Array.from(illustListElement.getElementsByClassName("list_more_link"))) {
if (moreLink.parentElement == null) {
continue;
}
moreLink.parentElement.appendChild(moreLink);
}
}
if (this.currentPage == PageType.PERSONALIZE) {
const brs = Array.from(illustListElement.getElementsByTagName("br"));
for (let br of brs) {
br.remove();
}
const items = Array.from(illustListElement.getElementsByClassName(pageInfos[this.currentPage].illustItemName));
for (let i = 0; i < items.length; i++) {
if ((i + 1) % 4 == 0 || i == items.length - 1) {
const br = document.createElement("br");
br.clear = "all";
items[i].insertAdjacentElement("afterend", br);
}
}
}
}
}
CreateUserLink(illustInfo) {
if (this.currentPage == PageType.PERSONALIZE || !this.option.createUserLink || illustInfo.element.getElementsByClassName("userLink").length > 0) {
return;
}
const userElement = illustInfo.element.getElementsByClassName("user")[0];
const userA = document.createElement("a");
userA.className = "userLink";
userA.href = "https://seiga.nicovideo.jp/user/illust/" + illustInfo.user.userId;
userA.style.left = "0";
userA.style.zIndex = "10";
userA.style.right = "10px";
userA.style.position = "absolute";
userA.style.border = "0";
userA.style.opacity = "0";
userA.addEventListener("mouseover", () => {
userA.style.border = "solid 1px silver";
userA.style.opacity = "0.3";
});
userA.addEventListener("mouseleave", () => {
userA.style.border = "0";
userA.style.opacity = "0";
});
if (this.currentPage == PageType.TAG_SEARCH) {
userA.style.height = "10px";
userA.style.top = "34px";
userA.style.backgroundColor = "silver";
}
if (this.currentPage == PageType.ILLUST) {
userA.style.height = "20px";
userA.style.top = "20px";
userA.style.backgroundColor = "black";
}
userElement.style.position = "relative";
userElement.style.zIndex = "20";
userElement.style.pointerEvents = "none";
userElement.insertAdjacentElement("beforebegin", userA);
}
DrawBlackWhiteButton(illustInfo) {
if (!this.option.createBlackWhiteButton) {
return;
}
if (illustInfo.user.status == Status.BLACK || illustInfo.user.status == Status.WHITE) {
if (illustInfo.user.status == Status.WHITE) {
const list = Array.from(illustInfo.element.getElementsByClassName("toListButton"));
for (let l of list) {
l.remove();
}
}
return;
}
if (illustInfo.element.getElementsByClassName("toListButton").length > 0) {
return;
}
const whiteButton = document.createElement("input");
const blackButton = document.createElement("input");
whiteButton.style.zIndex = "20";
whiteButton.style.visibility = "hidden";
if (this.currentPage == PageType.TAG_SEARCH) {
whiteButton.style.left = "117px";
whiteButton.style.top = "-30px";
whiteButton.style.width = "40px";
whiteButton.style.height = "25px";
whiteButton.style.position = "relative";
}
if (this.currentPage == PageType.ILLUST) {
whiteButton.style.left = "54px";
whiteButton.style.top = "-19px";
whiteButton.style.width = "30px";
whiteButton.style.height = "19px";
whiteButton.style.position = "relative";
}
if (this.currentPage == PageType.PERSONALIZE) {
whiteButton.style.top = "240px";
whiteButton.style.width = "40px";
whiteButton.style.height = "25px";
whiteButton.style.position = "absolute";
illustInfo.element.style.position = "relative";
illustInfo.element.style.height = "258px";
}
//上記のスタイルを両方に適用
blackButton.style.cssText = whiteButton.style.cssText;
whiteButton.type = "button";
blackButton.type = "button";
whiteButton.className = "toListButton";
blackButton.className = "toListButton";
whiteButton.name = "white";
blackButton.name = "black";
whiteButton.style.cssText += `background-color : white !important;`;
blackButton.style.cssText += `background-color : black !important;`;
if (this.currentPage == PageType.PERSONALIZE) {
whiteButton.style.left = "77px";
blackButton.style.left = "117px";
}
whiteButton.addEventListener("contextmenu", async (e) => {
e.preventDefault();
illustInfo.user.status = Status.OK;
for (let info of this.illustInfos) {
this.UpdateIllust(info);
}
this.UpdateIllustList();
this.DrawList();
await this.cacheStorage.SetStorageData(this.cache);
});
whiteButton.addEventListener("click", async () => {
illustInfo.user.status = Status.WHITE;
for (let info of this.illustInfos) {
this.UpdateIllust(info);
if (info.user.userId != illustInfo.user.userId) {
continue;
}
const buttons = info.element.getElementsByClassName("toListButton");
while (buttons.length != 0) {
buttons[0].remove();
}
}
this.UpdateIllustList();
this.DrawList();
await this.cacheStorage.SetStorageData(this.cache);
});
blackButton.addEventListener("contextmenu", async (e) => {
e.preventDefault();
illustInfo.user.status = Status.NG;
for (let info of this.illustInfos) {
this.UpdateIllust(info);
}
this.UpdateIllustList();
this.DrawList();
await this.cacheStorage.SetStorageData(this.cache);
});
blackButton.addEventListener("click", async () => {
illustInfo.user.status = Status.BLACK;
for (let info of this.illustInfos) {
this.UpdateIllust(info);
}
this.UpdateIllustList();
this.DrawList();
await this.cacheStorage.SetStorageData(this.cache);
});
if (this.currentPage == PageType.TAG_SEARCH) {
const infoElement = illustInfo.element.getElementsByClassName("illust_count")[0];
blackButton.addEventListener("mouseover", () => {
infoElement.style.opacity = "1";
});
blackButton.addEventListener("mouseleave", () => {
infoElement.style.opacity = "";
});
whiteButton.addEventListener("mouseover", () => {
infoElement.style.opacity = "1";
});
whiteButton.addEventListener("mouseleave", () => {
infoElement.style.opacity = "";
});
}
if (this.currentPage == PageType.ILLUST) {
const infoElement = illustInfo.element.getElementsByClassName("illust_info")[0];
blackButton.addEventListener("mouseover", () => {
infoElement.style.bottom = "0px";
});
blackButton.addEventListener("mouseleave", () => {
infoElement.style.bottom = "";
});
whiteButton.addEventListener("mouseover", () => {
infoElement.style.bottom = "0px";
});
whiteButton.addEventListener("mouseleave", () => {
infoElement.style.bottom = "";
});
}
illustInfo.element.addEventListener("mouseover", () => {
blackButton.style.visibility = "visible";
whiteButton.style.visibility = "visible";
});
illustInfo.element.addEventListener("mouseleave", () => {
blackButton.style.visibility = "hidden";
whiteButton.style.visibility = "hidden";
});
illustInfo.element.appendChild(whiteButton);
illustInfo.element.appendChild(blackButton);
}
async AddInfos(illustListElement) {
var _a, _b;
illustListElement.style.visibility = "hidden";
const illustElements = Array.from(illustListElement.getElementsByClassName(pageInfos[this.currentPage].illustItemName));
const illustIds = this.GetIllustIds(illustListElement);
const names = Array.from(illustListElement.getElementsByClassName("user"));
//console.log(illustIds);
//console.log(illustElements);
//console.log(names);
//キャッシュからの情報と合わせて追加(もうこれ分かんねぇこともある)
for (let i = 0; i < illustIds.length; i++) {
if (this.illustInfos.some(info => info.illustId == illustIds[i] && info.element == illustElements[i])) {
continue;
}
const info = this.GetInfo(illustIds[i]);
this.illustInfos.push({
name: (_b = (_a = names[i]) === null || _a === void 0 ? void 0 : _a.textContent) !== null && _b !== void 0 ? _b : "",
illustId: illustIds[i],
illust: info == undefined ? { created: "", id: "" } : info.illust,
user: info == undefined ? { illusts: [], status: Status.NONE, userId: "" } : info.user,
element: illustElements[i],
parent: illustListElement
});
}
}
SetCurrentPage(url) {
for (let i = 0; i < pageInfos.length; i++) {
if (pageInfos[i].regex.test(url)) {
this.currentPage = i;
return this.option.usePages[i];
}
}
this.currentPage = PageType.None;
return false;
}
GetPage() {
return this.currentPage;
}
//メインクラス、メイン関数の肥大化もう始まってる!
async Run(illustListElements) {
await Observer.DefinitelyGetElementByClassName(pageInfos[this.currentPage].illustListName);
await Observer.DefinitelyGetElementById("footer");
illustListElements = illustListElements !== null && illustListElements !== void 0 ? illustListElements : Array.from(document.getElementsByClassName(pageInfos[this.currentPage].illustListName));
for (let illustListElement of illustListElements) {
await this.AddInfos(illustListElement);
this.illustListElements.add(illustListElement);
}
//console.log("infos", this.illustInfos, this.illustInfos.length);
//これもう分かんねぇやつら
const unkownInfos = this.illustInfos.filter(info => info.user.userId == "");
//console.log("unkownInfos", unkownInfos);
//この戻り値なんかダサい・・・ダサくない?
const result = await Fetcher.FetchIllustDatas(unkownInfos.map(info => info.illustId));
//これもう分かんねぇやつらとキャッシュまで!?の情報更新
for (let i = 0; i < unkownInfos.length; i++) {
unkownInfos[i].illust = result.illusts[i];
let cachedUser = this.cache.find((c) => c.userId == result.userIds[i]);
if (cachedUser == undefined) {
unkownInfos[i].user.userId = result.userIds[i];
unkownInfos[i].user.status = Status.OK;
this.cache.push(unkownInfos[i].user);
}
else {
//キャッシュ使ったら後ろにしとく
this.cache = this.cache.filter(c => c.userId != (cachedUser === null || cachedUser === void 0 ? void 0 : cachedUser.userId));
this.cache.push(cachedUser);
unkownInfos[i].user = cachedUser;
}
unkownInfos[i].user.illusts.push(result.illusts[i]);
}
//増えすぎたキャッシュ削除
if (this.cache.length > 0) {
let okCount = 0;
for (let c of this.cache) {
if (c.status == Status.OK) {
okCount++;
}
}
while (okCount > this.option.okCacheMax) {
//OK以外消さない
if (this.cache[0].status != Status.OK) {
const c = this.cache.shift();
this.cache.push(c);
continue;
}
//今使ってたら消さない
if (this.illustInfos.some(info => info.user.userId == this.cache[0].userId)) {
break;
}
this.cache.shift();
okCount--;
}
}
//console.log(result);
//ブラック,ホワイトリストにないイラストエレメントにボタン追加
for (let illustInfo of this.illustInfos) {
this.DrawBlackWhiteButton(illustInfo);
this.CreateUserLink(illustInfo);
}
if (this.option.judge.isJudge) {
//情報取ってきた投稿者の荒らし判定更新 ↓これは重複排除
for (let c of [...new Set(unkownInfos.map(u => u.user))]) {
this.CheckArasi(c);
}
}
await this.cacheStorage.SetStorageData(this.cache);
for (let info of this.illustInfos) {
this.UpdateIllust(info);
}
this.UpdateIllustList();
for (let illustListElement of illustListElements) {
illustListElement.style.visibility = "visible";
}
await this.SetOptionButton();
this.DrawList();
}
async StartObserve() {
const illustListParent = (await Observer.DefinitelyGetElementByClassName(pageInfos[this.currentPage].illustListName)).parentNode;
const mutationObserver = new MutationObserver(async (mrs) => {
for (let mr of mrs) {
for (let i = 0; i < mr.addedNodes.length; i++) {
const element = mr.addedNodes[i];
if (element.classList != null && element.classList.contains(pageInfos[this.currentPage].illustListName)) {
await main.Run([element]);
}
}
}
});
mutationObserver.observe(illustListParent !== null && illustListParent !== void 0 ? illustListParent : document, {
childList: true,
subtree: true
});
}
}
;
const main = new Main();
await main.GetStorageData();
await main.SetOptionButton();
const isUseNG = main.SetCurrentPage(location.href);
if (!isUseNG) {
return;
}
await main.Run();
await main.StartObserve();
})();