您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Code I don't want to write again
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/441792/1270274/CIDWWA.js
// ==UserScript== // @name CIDWWA // @namespace http://tampermonkey.net/ // @version 0.3.2 // @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 = 6; 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; const modalStyle = new Style(); modalStyle.setStyle({ ".cidwwa-modal": { background: "var(--color-menu,#f4f4f4)", border: "1px solid black", borderRadius: "5px", padding: "16px 12px 16px", pointerEvents: "auto", margin: "0", position: "absolute", }, }); const itemContainerStyle = new Style(); itemContainerStyle.setStyle({ ".modal-itemcontainer": { background: "var(--color-menu, white)", borderRadius: "5px", padding: "16px", display: "flex", justifyContent: "center", overflowX: config.overflowX ?? "initial", overflowY: config.overflowY ?? "initial", height: config.height ?? "initial", width: config.width ?? "initial", }, }); const modalTitleStyle = new Style(); modalTitleStyle.setStyle({ ".cidwwa-modal-title": { fontSize: "18px", fontFamily: "'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif", fontWeight: "300", }, }); const headerStyle = new Style(); headerStyle.setStyle({ ".cidwwa-header": { display: "flex", justifyContent: "space-between", userSelect: "none", }, }); const dragStyle = new Style(); dragStyle.setStyle({ ".cidwwa-drag": { position: "absolute", top: "0", left: "0", height: "48px", width: "calc(100% - 48px)", }, }); if (config.preventDragging) { modalStyle.addStyle({ ".cidwwa-modal": { top: "50%", left: "50%", transform: "translate(-50%, -50%)", }, }); } else { dragStyle.addStyle({ ".cidwwa-drag": { cursor: "move", }, }); } this.#container.innerHTML = ` <section class="cidwwa-modal"> <div class="cidwwa-header"> <h3 style="margin: 0 0 10px 12px" class="cidwwa-modal-title">${ config.title ?? "" }</h3> <i class="fa fa-times" style="font-size: 20px; cursor: pointer;"></i> </div> <div class="cidwwa-drag" style="${dragStyle}"></div> <div class="modal-itemcontainer"> </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); } } resetScroll() { this.#itemContainer.scrollTo(0, 0); } } class WKButton { #container; #button; #dropdown; #onTurnOn = []; #onTurnOff = []; #state = false; constructor(config) { this.#container = document.createElement("li"); 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> `; const addToSite = () => { const sitemap = document.querySelector("#sitemap,#sitmap"); sitemap.insertBefore(this.#container, sitemap.firstChild); }; addToSite(); const observer = new MutationObserver(() => { if (!document.body.contains(this.#container)) { addToSite(); } }); observer.observe(document.body, { childList: true, }); 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(--color-menu, var(--dropdown-background)); } `; }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址