您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Code I don't want to write again
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/441792/1062515/CIDWWA.js
// ==UserScript== // @name CIDWWA // @namespace http://tampermonkey.net/ // @version 0.3.0 // @description Code I don't want to write again // @author Gorbit99 // @icon https://www.google.com/s2/favicons?sz=64&domain=wanikani.com // @grant none // @license MIT // ==/UserScript== "use strict"; const version = 4; class Modal { #container; #itemContainer; #modal; #open = false; #onOpen = []; #onClose = []; #draggable; constructor(config) { this.#container = document.createElement("div"); const dashboard = document.querySelector(".dashboard"); if (dashboard) { dashboard.append(this.#container); } else { document.body.append(this.#container); } this.#container.style.position = "fixed"; this.#container.style.inset = "0"; this.#container.style.display = "none"; if ((config.clickOutAction ?? "none") === "none") { this.#container.style.pointerEvents = "none"; } else { this.#container.style.pointerEvents = "auto"; } this.#container.style.zIndex = "9999"; this.#container.style.background = config.tintBackground ? "#000a" : "transparent"; this.#draggable = !config.preventDragging; let modalStyle = ` background: #f4f4f4; border: 1px solid black; border-radius: 5px; padding: 16px 12px 12px; pointer-events: auto; margin: 0; position: absolute; `; const itemContainerStyle = ` border-radius: 5px; padding: 16px; display: flex; justify-content: center; overflow-x: ${config.overflowX ?? "initial"}; overflow-y: ${config.overflowY ?? "initial"}; height: ${config.height}; width: ${config.width}; `; const headerStyle = ` display: flex; justify-content: space-between; user-select: none; `; let dragStyle = ` position: absolute; top: 0; left: 0; height: 48px; width: calc(100% - 48px); `; if (config.preventDragging) { modalStyle += ` top: 50%; left: 50%; transform: translate(-50%, -50%); `; } else { dragStyle += ` cursor: move; `; } this.#container.innerHTML = ` <section style="${modalStyle}" class="cidwwa-modal"> <div style="${headerStyle}" class="cidwwa-header"> <h3 style="margin: 0 0 10px 12px">${config.title ?? ""}</h3> <i class="fa fa-times" style="font-size: 20px; cursor: pointer;"></i> </div> <div class="cidwwa-drag" style="${dragStyle}"></div> <div style="${itemContainerStyle}" class="modal-itemcontainer bg-white"> </div> </div> `; if (config.clickOutAction === "close") { this.#container.addEventListener("click", () => this.close()); } this.#itemContainer = this.#container.querySelector(".modal-itemcontainer"); this.#container.querySelector("i").addEventListener("click", () => this.close()); if (!config.preventDragging) { const drag = this.#container.querySelector(".cidwwa-drag"); this.#modal = this.#container.querySelector(".cidwwa-modal"); let startX; let startY; let isDragging = false; drag.addEventListener("mousedown", (e) => { if (e.button !== 0) { return; } startX = e.offsetX; startY = e.offsetY; isDragging = true; }); window.addEventListener("mousemove", (e) => { if (!isDragging) { return; } e.preventDefault(); const mousePosX = e.clientX; const mousePosY = e.clientY; let newPosX = mousePosX - startX; let newPosY = mousePosY - startY; const screenWidth = document.body.clientWidth; const screenHeight = document.body.clientHeight; newPosX = Math.min(Math.max(newPosX, 0), screenWidth - this.#modal.offsetWidth - 1); newPosY = Math.min(Math.max(newPosY, 0), screenHeight - this.#modal.offsetHeight - 1); this.#modal.style.left = `${newPosX}px`; this.#modal.style.top = `${newPosY}px`; }); window.addEventListener("mouseup", (e) => { if (!isDragging) { return; } if (e.button !== 0) { return; } isDragging = false; }); } this.#modal.addEventListener("click", (e) => { e.stopPropagation(); }); } toggle() { this.#open = !this.#open; this.#container.style.display = this.#open ? "block" : "none"; if (this.#open) { this.#onOpen.forEach((callback) => callback()); if (this.#draggable) { const screenWidth = document.body.clientWidth; const screenHeight = document.body.clientHeight; const modalWidth = this.#modal.offsetWidth; const modalHeight = this.#modal.offsetHeight; const newPosX = (screenWidth - modalWidth) / 2; const newPosY = (screenHeight - modalHeight) / 2; this.#modal.style.left = `${newPosX}px`; this.#modal.style.top = `${newPosY}px`; } } else { this.#onClose.forEach((callback) => callback()); } return this.#open; } open() { if (this.#open) { return; } this.toggle(); } close() { if (!this.#open) { return; } this.toggle(); } onOpen(callback) { this.#onOpen.push(callback); } onClose(callback) { this.#onClose.push(callback); } setContent(content) { if (typeof content === "string") { this.#itemContainer.innerHTML = content; } else { this.#itemContainer.children.forEach((child) => child.remove()); this.#itemContainer.append(content); } } } class WKButton { #container; #button; #dropdown; #onTurnOn = []; #onTurnOff = []; #state = false; constructor(config) { const sitemap = document.querySelector("#sitemap"); this.#container = document.createElement("li"); sitemap.insertBefore(this.#container, sitemap.firstChild); this.#container.classList.add("sitemap__section"); this.#container.innerHTML = ` <button class="sitemap__section-header wk-custom-button"> <span lang="ja">${config.japaneseText}</span> <span lang="en">${config.englishText}</span> </button> `; this.#button = this.#container.querySelector(".wk-custom-button"); if (config.color) { this.#button.dataset.color = config.color; this.#button.style.setProperty("--focus-color", config.color); } if (config.hoverColor) { this.#button.dataset.hoverColor = config.hoverColor; this.#button.style.setProperty("--hover-color", config.hoverColor); } this.#button.addEventListener("click", () => { this.setState(!this.#state); if (this.#state) { this.#onTurnOn.forEach((callback) => callback()); } else { this.#onTurnOff.forEach((callback) => callback()); } }); if (config.withDropdown) { this.attachDropdown(config.withDropdown); } } attachDropdown(config) { if (this.#dropdown) { throw "A dropdown is already attached!"; } this.#dropdown = document.createElement("div"); this.#dropdown.style.zIndex = 899; this.#dropdown.classList.add("sitemap__expandable-chunk"); this.#dropdown.dataset.expanded = false; this.#container.append(this.#dropdown); this.#dropdown.style.setProperty("--dropdown-background", config.bgColor); let clickIn = false; document.addEventListener("click", () => { if (!clickIn && this.#state) { this.setState(false); this.#onTurnOff.forEach((callback) => callback()); } clickIn = false; }); this.#dropdown.addEventListener("click", () => { clickIn = true; }); this.#button.addEventListener("click", () => { clickIn = true; }); } setDropdownContent(content) { if (typeof content === "string") { this.#dropdown.innerHTML = content; } else { this.#dropdown.children.forEach((child) => child.remove()); this.#dropdown.append(content); } } attachSubtext() { let subtext = this.#button.parentNode.querySelector(".button-subtext"); if (subtext) { return subtext; } const subtextContainerStyle = ` width: 100%; display: inline-flex; justify-content: center; position: absolute; margin-top: 4px; `; const subtextStyle = ` color: #999; font-size: 14px; line-height: 0; `; this.#button.insertAdjacentHTML("afterend", ` <span class="button-subtext-container" style="${subtextContainerStyle}"> <span class="button-subtext" style="${subtextStyle}"></span> </span> `); subtext = this.#button.parentNode.querySelector(".button-subtext"); return subtext; } onTurnOn(callback) { this.#onTurnOn.push(callback); } onTurnOff(callback) { this.#onTurnOff.push(callback); } setState(state) { this.#state = state; this.#button.dataset.expanded = state; if (this.#dropdown) { this.#dropdown.dataset.expanded = state; } } } class Style { #styleElement; constructor() { this.#styleElement = document.createElement("style"); document.head.append(this.#styleElement); } setStyle(styleData) { this.#styleElement.innerHTML = ""; this.addStyle(styleData); } addStyle(styleData) { const blocks = []; for (let key in styleData) { blocks.push(this.#parseStyleBlock(key, styleData[key])); } this.#styleElement.innerHTML += blocks.join("\n"); } #parseStyleBlock(selector, styleBlock) { const properties = []; const blocks = []; for (let key in styleBlock) { if (typeof styleBlock[key] === "object") { let newSelector = key; if (newSelector.includes("&")) { newSelector = newSelector.replaceAll("&", selector); } else { newSelector = selector + " " + newSelector; } blocks.push(this.#parseStyleBlock(newSelector, styleBlock[key])); } else { let property = key.replaceAll(/[A-Z]/g, (match) => "-" + match.toLowerCase()); properties.push(property + ":" + styleBlock[key]); } } blocks.unshift(`${selector}{${properties.join(";")}}`); return blocks.join("\n"); } } if (!window.cidwwaVersion || window.cidwwaVersion < version) { window.cidwwaVersion = version; window.createModal = function(config) { return new Modal(config); }; window.createButton = function(config) { return new WKButton(config); }; window.createStyle = function(config) { return new Style(config); }; const styleElement = document.createElement("style"); document.head.append(styleElement); styleElement.innerHTML = ` .wk-custom-button[data-color][data-expanded="true"], .wk-custom-button[data-color]:focus { color: var(--focus-color); border-color: var(--focus-color); } .wk-custom-button[data-hover-color]:not([data-expanded="true"]):not(:focus):hover { color: var(--focus-color); border-color: var(--hover-color); } .wk-custom-button + .sitemap__expandable-chunk, .wk-custom-button + .sitemap__expandable-chunk:before { background-color: var(--dropdown-background); } `; }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址