您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Chants script for NovelAI
当前为
// ==UserScript== // @name Chants for NovelAI // @namespace https://www6.notion.site/dc99953d5f04405c893fba95dace0722 // @version 4 // @description Chants script for NovelAI // @author SenY // @match https://novelai.net/image // @icon https://www.google.com/s2/favicons?sz=64&domain=novelai.net // @grant none // @license MIT // ==/UserScript== (function () { const colors = { "-1": ["red", "maroon"], "0": ["lightblue", "dodgerblue"], "1": ["gold", "goldenrod"], "3": ["violet", "darkorchid"], "4": ["lightgreen", "darkgreen"], "5": ["tomato", "darksalmon"], "6": ["red", "maroon"], "7": ["whitesmoke", "black"], "8": ["seagreen", "darkseagreen"] } const getChantURL = function (force) { if (force === true) { localStorage.removeItem("chantURL"); } let chantURL = localStorage.getItem("chantURL") || prompt("Input your chants json url.\nThe URL must be a Cors-enabled server (e.g., gist.github.com).", "https://gist.githubusercontent.com/vkff5833/989808aadebf8648831955cdf2a7b3e3/raw/yuuri.json"); if (chantURL) { localStorage.setItem("chantURL", chantURL); } return chantURL; } let chantURL = getChantURL(null); let ui = document.createElement("div"); setInterval(() => { document.querySelectorAll("textarea[placeholder]").forEach(el => { if (el.offsetParent) { el.parentElement.appendChild(ui); } }); }, 500); let allTags = []; fetch("https://gist.githubusercontent.com/vkff5833/275ccf8fa51c2c4ba767e2fb9c653f9a/raw/danbooru.json", { method: "GET", }).then((response) => response.json()) .then((data) => { allTags = data; fetch("https://gist.githubusercontent.com/vkff5833/275ccf8fa51c2c4ba767e2fb9c653f9a/raw/danbooru_wiki.slim.json", { method: "GET", }).then((response) => response.json()) .then((wikiPages) => { allTags = allTags.map(x => { let wikiPage = wikiPages.find(y => y.name == x.name); if(wikiPage){ x.terms = x.terms.concat(wikiPage.otherNames); } return x; }); }); }); let chants = []; const Append = function (key, value) { let text; let newTags; let textarea = document.querySelector("textarea[placeholder]"); let oldTags = textarea.value.split(",").map(x => x.trim()); if (key) { let chant = chants.find(x => x.name == key.trim()); if (chant) { newTags = chant.content.split(",").map(x => x.trim()); } } if (value) { newTags = [value.trim()]; if (oldTags[oldTags.length - 1]) { oldTags.pop(); } } if (newTags.length) { let tags = oldTags.concat(newTags).filter(x => x); textarea.textContent = tags.join(", ").replace(/^, /g, ""); textarea.value = tags.join(", ").replace(/^, /g, "") + ","; } } const Suggest = function () { let tags = document.querySelector("textarea[placeholder]"); if (tags) { tags = tags.value.split(",").map(x => x.trim()) if (tags.length) { let tag = tags[tags.length - 1]; document.getElementById("suggestionField").textContent = ""; let suggestions = allTags.filter(x => x.name.search(tag.replace(/_/g, " ")) >= 0).slice(0, 10); suggestions = suggestions.concat(allTags.filter(x => { return x.terms.map(y => y.search(tag.replace(/_/g, " ")) >= 0).includes(true); }).slice(0, 10)); let done = new Set(); suggestions.forEach(tag => { if (!done.has(tag.name)) { let button = document.createElement("button"); let count = tag.coumt; if (count > 1000) { count /= 1000; count = Math.round(count * 10) / 10; count += "k"; } button.textContent = tag.name + " (" + count + ")"; button.style.color = colors[tag.category][1]; button.addEventListener("click", function () { Append(null, tag.name); }); document.getElementById("suggestionField").appendChild(button); } done.add(tag.name); }); } } } const Build = function () { ui.textContent = ""; let hr = document.createElement("hr"); hr.style.color = "grey"; hr.style.borderWidth = "2px"; let optionField = document.createElement("div"); let chantsField = document.createElement("div"); let suggestionField = document.createElement("div"); suggestionField.setAttribute("id", "suggestionField"); ui.appendChild(optionField); ui.appendChild(hr.cloneNode()); ui.appendChild(chantsField); ui.appendChild(hr.cloneNode()); ui.appendChild(suggestionField); let resetButton = document.createElement("button"); resetButton.textContent = "Reset Chants URL"; resetButton.style.color = "red"; resetButton.addEventListener("click", function () { chantURL = getChantURL(true); Build(); }); optionField.appendChild(resetButton); let clearButton = document.createElement("button"); clearButton.textContent = "Clear Suggestion"; clearButton.style.color = "red"; clearButton.addEventListener("click", function () { document.getElementById("suggestionField").textContent = ""; }); optionField.appendChild(clearButton); fetch(chantURL, { method: "GET", }).then((response) => response.json()) .then((data) => { chants = data; chants.forEach(chant => { let button = document.createElement("button"); button.textContent = chant.name; button.style.color = colors[chant.color][1]; button.addEventListener("click", function () { Append(chant.name, null); }); chantsField.appendChild(button); }); }); } let init = false; document.addEventListener("DOMContentLoaded", function () { if (init === false) { Build(); init = true; } }); document.addEventListener("keyup", function () { Suggest(); }); })();