网页美化
// ==UserScript== // @name 网页滚动条美化V2 // @namespace http://tampermonkey.net/ // @version 0.2.2 // @description 网页美化 // @author Eliauk // @match https://*/* // @match http://*/* // @icon data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAwIiBoZWlnaHQ9IjUwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMCAwIDExNy4yOSAxMDAuNCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJlNmM2YzNkZi04OTIzLTQyZTMtYWI5NS03OWRhZWQzNWVlYmIiIHgxPSIyNi40MiIgeTE9Ijg2Ljk4IiB4Mj0iOTYuOCIgeTI9IjE2LjYxIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEsIDAsIDAsIC0xLCAwLCAxMDIuMDUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZiMmMyIj48L3N0b3A+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZjg1ZThhIj48L3N0b3A+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHRpdGxlPjc2MDg8L3RpdGxlPjxnIGlkPSJiNmU5YjlmZi05NTU5LTQyMTQtOWQxMi0zODQ2YWViNmQxM2UiPjxnIGlkPSJhMjM3NmQ3ZC04MDgwLTQwYjMtYjAyZi03OWYxYWMzZWJlYzAiPjxwYXRoIGQ9Ik01OS4zNiw0N0M1My4yOSw0OCw1Mi4yNiw1Ny4xLDYyLjc0LDU5Ljg0czI2LjQyLjQ1LDI2Ljg4LTIwUzUzLjE4LDYuMywzNy40NiwzMC4yMiwzNS4xMSw4MS42Nyw1OS43OCw4My43NmMyMC4yOCwxLjcxLDMxLjQ0LTUuNywzNi40NS05LjExczEyLjA3LS4yMywyLDkuMzQtNDQuNDIsMjMuOTMtNzMtMi40Qy0xLjUxLDU2LjkzLDYsMTYuMjIsNDcuODIsNiw5NC41NC01LjQxLDEyMC40NywzNy4yNCwxMDEsNjEuNzgsODMuODIsODMuNDIsNDUuODgsNzAuMzIsNDkuMDcsNDguOSw1MiwyOS40OCw3Mi43NywzMC4yMiw3My4yMiw0MCw3My41MSw0Ni4yNyw2NS4yOCw0NS45Myw1OS4zNiw0N1oiIGZpbGw9InVybCgjZTZjNmMzZGYtODkyMy00MmUzLWFiOTUtNzlkYWVkMzVlZWJiKSI+PC9wYXRoPjxwYXRoIGQ9Ik04Mi42MSw5NS44OWMtMS41Mi0uNDUtMy4xNy0uODgtNC45Mi0xLjM0LTEyLjU5LTMuMzItMzAuMzgtNy43OC00MS0yMy43MS03LjYzLTEwLjY4LTguNjUtMjYuMjkuNzYtNDAuNjIsOS4xNS0xMy45MiwyNS40Ny0xNS4zNCwzNy40My0xMC0xMi4wNy03LjM2LTQ4LjI4LTQuNzgtNTIsMzcuMDhBMzcuMzUsMzcuMzUsMCwwLDAsMzcuMDUsOTAuMTJDNDYsOTcuMjgsNTguNzYsMTAxLjM3LDc0LjM3LDEwMC4yLDg2LjY1LDk5LjI3LDg3LjI5LDk3LjI2LDgyLjYxLDk1Ljg5Wm0tMjYuODguM2E1Myw1MywwLDAsMS01LjI5LS45NEE0OS40Nyw0OS40NywwLDAsMSw0NS4xLDkzLjdhNTIuNzgsNTIuNzgsMCwwLDEtNS4zNy0yLjIsNTIuNzgsNTIuNzgsMCwwLDAsNS4zNywyLjIsNDkuNDcsNDkuNDcsMCwwLDAsNS4zNCwxLjU1LDUzLDUzLDAsMCwwLDUuMjkuOTRjMS43NS4yMiwzLjQ4LjM1LDUuMTguNEM1OS4yMSw5Ni41NCw1Ny40OCw5Ni40MSw1NS43Myw5Ni4xOVoiIGZpbGw9IiMzYzIyOTkiIG9wYWNpdHk9IjAuNSIgc3R5bGU9Imlzb2xhdGlvbjppc29sYXRlIj48L3BhdGg+PHBhdGggZD0iTTEwNC4zMywxOS42N0MxMDEuMjYuMSw3OS40Ni0zLjUzLDYwLjEzLDQuMTcsNDAuMjEsMTIuMTEsMjIuOTIsMzIuMDksMzEuNDgsNTljLTItOC45Mi0uMzYtMTkuMTYsNi0yOC44MiwxNS43LTIzLjksNTIuNi0xMC45MSw1Mi4xNCw5LjU5cy0xNi40LDIyLjc4LTI2Ljg4LDIwUzUzLjI5LDQ4LDU5LjM2LDQ3YzUuOTItMSwxNC4xNS0uNjksMTMuODYtNi45NEM3Mi43NywzMC4yMiw1MiwyOS40OCw0OS4wNyw0OC45YTE2LjYzLDE2LjYzLDAsMCwwLDIuMDcsMTAuODdjOS4xNywxNS43Miw1Mi44NSw5LDUzLjkyLTI5LjRBNTksNTksMCwwLDAsMTA0LjMzLDE5LjY3WiIgZmlsbD0iI2ZmM2UyNCIgb3BhY2l0eT0iMC41Ij48L3BhdGg+PHBhdGggZD0iTTMyLjExLDEyQzE4LjU3LDE0LjEyLDYuNzcsMTkuNzksMi4yNywyOC40MWMtNS40NSwxMC40NC0uNzIsMjQsMTAuMzEsMzUuMDlTNDEsODMuMjgsNjAuOCw4My44NGwtMS0uMDhjLTI0LjY3LTIuMDktMzgtMjkuNjItMjIuMzItNTMuNTQsMTEuOTMtMTguMTUsMzYuMDctMTUsNDYuODEtMy41M0M3My44OCwxMy4zNyw1MS4yNiw5LjEsMzIuMTEsMTJaIiBmaWxsPSIjZmYwMDk4IiBvcGFjaXR5PSIwLjYiPjwvcGF0aD48cGF0aCBkPSJNMTAzLjQxLDcxLjM1Yy44MywyLjE1LDE1LjU1LTEsMTMuNzItNS44M1MxMDIuNTcsNjkuMiwxMDMuNDEsNzEuMzVaTTM0LjcsOGMyLjMuMTcsNC45NC03LjQ3LS4xNy04UzMyLjQxLDcuNzYsMzQuNyw4WiIgZmlsbD0iI2Y3NTdhZiI+PC9wYXRoPjxwYXRoIGQ9Ik0xMDIuNDUsNjZjLjQ0LDIuNTUsNi0yLDQuMzItNC4wNlMxMDIuMTcsNjQuMzcsMTAyLjQ1LDY2Wk05LjU4LDY1Yy00LjM1Ljc0LTIuMTEsNi4yOSwxLjMyLDMuNUMxMi44NSw2Ni45MywxMiw2NC42MSw5LjU4LDY1WiIgZmlsbD0iI2FiOGVlYiI+PC9wYXRoPjxwYXRoIGQ9Ik0zMS44Myw4LjYxYy0uNDktMi40NS0zLjE0LTYuNDctNi40Ni03LjA5LTIuNzktLjUtNy44Niw1LjMyLDEuNzUsOC4zNEMzMi42MywxMS41OSwzMi4wNiw5Ljc5LDMxLjgzLDguNjFaIiBmaWxsPSIjZmZiZDg4Ij48L3BhdGg+PC9nPjwvZz48L3N2Zz4= // @license GPL-3.0 // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_getResourceText // @grant GM_notification // @resource ArcoDesignStyle https://gitee.com/lzyws739307453/scrollbar-beautify/raw/master/arcodesign.min.css // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @run-at document-start // ==/UserScript== const isdebug = false; // 调试日志用 const isLocalDebug = false; // 加载本地资源用 const debug = isdebug ? console.log.bind(console) : () => {}; let nodes, scrollbarX, scrollbarY, ruleTitles, ruleConfig; let data = {}; const DefaultConfig = { scrollbar: { height: 10, width: 10, radius: 10, background: "linear-gradient(45deg, #000000 0%, #ff0000 100%) content-box;", color: { default: "#f2f3f5", solid: "#f2f3f5", gradient: { direction: 45, length: 1, steps: { "0": "#000000", "1": "#ff0000" } } } }, rule: { default: ["^((ht|f)tps?:\\/\\/)?[\\w-]+(\\.[\\w-]+)+"], titles: ["^https?:\\/\\/(.+\\.)?bilibili\\.[a-z]{2,6}/?"], config: { "^((ht|f)tps?:\\/\\/)?[\\w-]+(\\.[\\w-]+)+": { enable: true, style: "::-webkit-scrollbar{width:10px;height:10px;}::-webkit-scrollbar-thumb{border-radius:10px;border:2px solid transparent;background:linear-gradient(45deg, #000000 0%, #ff0000 100%) content-box;}::-webkit-scrollbar-track{box-shadow:none;}html{overflow-y:overlay;}" }, "^https?:\\/\\/(.+\\.)?bilibili\\.[a-z]{2,6}/?": { enable: true, style: "html{overflow-y:inherit;}body{overflow-y:overlay;}" } } } } // 增加了一个css的缓冲层,保证多次CSS操作不导致页面卡顿,减少重排的次数 class FlushDomFragment { constructor() { this.init() } init() { this.length = 0 this.fragmentHead = document.createDocumentFragment(); this.fragmentBody = document.createDocumentFragment(); this.fragmentDOM = document.createDocumentFragment(); this.reloadList = [] // 所有需要动态刷新的都在这里面 } _removeReload() { this.reloadList.map(selector => { safeRemove(selector) }) } _singleInsert(node, toDom, checkDom) { if (!node) return; const { dataset: { xclass: selector = '' } = {}, tagName = '' } = node if (tagName.toLowerCase() === 'style') { if (selector) { // 已经存在,不用添加 if (checkDom.querySelector(selector)) return } else { console.error('出现没有样式的节点', node) } } // 添加 toDom.appendChild(node) this.length += 1 debug('增加节点', node) debug('长度变化', this.length) } // 如果CSS已经存在了,那么就不再添加了 _dropMultiCSS(fragment) { const newFrag = document.createDocumentFragment(); [...fragment.childNodes].map(node => { this._singleInsert(node, newFrag, document) }) return newFrag } flush() { // 有数据, 才进行flush, 否则没有必要 if (this.length <= 0) return this._removeReload() // MARK 保证线程安全, 将现有数据暂存, 然后生成新的节点, 避免其他js插入后丢失 const curBodyFrag = this.fragmentBody const curHeadFrag = this.fragmentHead const curDomFrag = this.fragmentDOM this.init() // 数据清除 const newBodyFrag = this._dropMultiCSS(curBodyFrag) const newHeadFrag = this._dropMultiCSS(curHeadFrag) const newDomFrag = this._dropMultiCSS(curDomFrag) debug('数据flush1', newBodyFrag.children.length) debug('数据flush2', newHeadFrag.children.length) debug('数据flush3', newDomFrag.children.length) safeWaitFunc("body", () => { document.body.appendChild(newBodyFrag) }) safeWaitFunc("head", () => { document.head.appendChild(newHeadFrag) }) document.insertBefore(newDomFrag, document.documentElement) } appendChild(node, to = 'head', config = { isReload: false }) { return this.insert(node, to, config) } /** * * @param { 子节点 } node * @param { 父节点 } to * @param { 配置信息, isReload: 是否加入定时器刷新重新加载 } config * @returns */ insert(node, to = 'head', config = { isReload: false }) { if ('body' === to) { this._singleInsert(node, this.fragmentBody, this.fragmentBody) } else if ('head' === to) { this._singleInsert(node, this.fragmentHead, this.fragmentHead) } else if ('DOM' === to) { this._singleInsert(node, this.fragmentDOM, this.fragmentDOM) } else { console.error('不支持的节点操作') return } const { isReload } = config if (isReload) { const { classList = [] } = node if (classList.length) { this.reloadList.push('.' + [...(classList || [])].join('.')) } else { console.error('异常的reload参数, 没有classList', node) } } return this } } function $one(selector, element = document) { return element.querySelector(selector) } function $all(selector, element = document) { return element.querySelectorAll(selector) } function parseBoolean(val) { if (["yes", "y", "true", "1", "on"].indexOf(String(val).toLowerCase()) !== -1) return true; if (["no", "n", "false", "0", "off"].indexOf(String(val).toLowerCase()) !== -1) return false; return Boolean(val); } ruleConfigSwitch = function (e) { const enable = parseBoolean(e.getAttribute("aria-checked")); const data_v = e.dataset.v; const titleComp = $one(`.arco-collapse-item-header-title[data-v="${data_v}"]`, ruleConfig); const title = titleComp.innerText; if (!data.rule.config[title]) { data.rule.config[title] = {}; } debug('ruleConfigSwitch', data.rule.config[title]); debug('ruleConfigSwitch', data); data.rule.config[title].enable = enable; } // 渐变长度更改事件 gradientLenghtChange = function (e) { // debug("gradientLenghtChange"); // debug(e.value); nodes.color.gradient.step nodes.color.gradient.step.comp.setAttribute("max", `${e.value}`); // 重置 resetGradientStep("0"); data.scrollbar.color.gradient.steps = {}; data.scrollbar.color.gradient.length = e.value; resetGradientColor(data.scrollbar.color.default); resetPreviewBackground(data.scrollbar.color.default); redrawSliderStyle(nodes.color.gradient.step.comp); } // 纯色、渐变选择按钮事件 colorSelect = function (e) { // debug(e); const select = $one("#eliauk-container .arco-radio-checked .arco-radio-target", e).value; if ('GradientColor' === select) { $one("#solid-color-page").style.display = 'none'; $one("#gradient-color-page").style.display = 'block'; reloadGradientPage(); } else { $one("#gradient-color-page").style.display = 'none'; $one("#solid-color-page").style.display = 'block'; reloadSolidPage(); } }; // 滑动输入条绘制 function redrawSliderStyle(ele) { let total = ele.max - ele.min; let effset = Math.round((ele.value * 100) / total); ele.style.background = `linear-gradient(to right, rgb(var(--primary-6)) ${effset}%, var(--color-fill-3) ${effset}%)`; }; function resetGradientStep(value) { const step = nodes.color.gradient.step.comp; step.value = value; let total = step.max - step.min; let effset = Math.round((value * 100) / total); nodes.color.gradient.step.text.value = `${effset}%`; redrawSliderStyle(nodes.color.gradient.step.comp); reloadGradientPreviewBackground(); } function resetGradientColor(value) { nodes.color.gradient.color.comp.value = value; nodes.color.gradient.color.text.value = value; } function resetPreviewBackground(background) { data.scrollbar.background = background; $all("#eliauk-container .context div").forEach(ele => { ele.style.background = background; }) } function resetPreviewBasicSettings(width, height, radius) { $all("#eliauk-container .context div").forEach(ele => { ele.style.borderRadius = radius; }) scrollbarY.style.width = `${width}px`; scrollbarX.style.height = `${height}px`; } function reloadBasicSettingsPage() { const { width, height, radius } = data.scrollbar; nodes.scrollbar.width.comp.value = width; nodes.scrollbar.width.text.value = width; nodes.scrollbar.height.comp.value = height; nodes.scrollbar.height.text.value = height; nodes.scrollbar.radius.comp.value = radius; nodes.scrollbar.radius.text.value = radius; resetPreviewBasicSettings(width, height, radius); } function reloadSolidPage() { nodes.color.solid.color.comp.value = data.scrollbar.color.solid; nodes.color.solid.color.text.value = data.scrollbar.color.solid; resetPreviewBackground(data.scrollbar.color.solid); } function reloadGradientDirection() { nodes.color.gradient.direction.comp.value = data.scrollbar.color.gradient.direction; nodes.color.gradient.direction.text.value = `${data.scrollbar.color.gradient.direction}deg`; } // 渐变背景修改预览 function reloadGradientPreviewBackground() { const gradientDirection = nodes.color.gradient.direction.text.value; const keys = Object.keys(data.scrollbar.color.gradient.steps); // .sort((a, b) => a.match(/^(\d+)%$/)[1] - b.match(/^(\d+)%$/)[1]) const style = `linear-gradient(${gradientDirection}, ${keys.map((key) => { let total = data.scrollbar.color.gradient.length; let effset = Math.round((key * 100) / total); return `${data.scrollbar.color.gradient.steps[key]} ${effset}%` }).join(", ")})` // debug(style); resetPreviewBackground(style); } function reloadRules() { ruleTitles.value = data.rule.titles.join(";\n"); } function reloadGradientPage() { nodes.color.gradient.length.text.value = data.scrollbar.color.gradient.length; nodes.color.gradient.step.comp.max = data.scrollbar.color.gradient.length; nodes.color.gradient.direction.comp.value = data.scrollbar.color.gradient.direction; nodes.color.gradient.direction.text.value = `${data.scrollbar.color.gradient.direction}deg`; redrawSliderStyle(nodes.color.gradient.direction.comp); const steps = data.scrollbar.color.gradient.steps; const keys = Object.keys(steps); if (keys && keys.length > 0) { resetGradientStep(keys[0]); resetGradientColor(steps[keys[0]]); } else { resetGradientStep("0"); resetGradientColor(data.scrollbar.color.default); } }; /** * * @param { css选择器 } selector * @param { 是否绑定消失动画 } withAni */ function safeRemove(selector, withAni = false) { safeFunction(() => { let removeNodes = document.querySelectorAll(selector); for (let i = 0; i < removeNodes.length; i++) { aniRemove(removeNodes[i], withAni) } }) } /** * * @param { 节点 } node * @param { 是否绑定消失动画 } withAni */ function aniRemove(node, withAni) { if (withAni) { node.classList.add('aniDelete') setTimeout(() => { node.remove(); }, 200) } else { node.remove(); } } function safeFunction(func, failCb) { try { func(); } catch (e) { failCb && failCb(e) } } function retryInterval(callback, period = 50, now = false, count = -1) { if (now && count-- != 0) { if (callback()) return; } const inter = setInterval(() => { if (count-- === 0) { return clearInterval(inter); } callback() && clearInterval(inter); }, period); } function safeWaitFunc(selector, callbackFunc, time = 60, notClear) { notClear = notClear || false; let doClear = !notClear; retryInterval(() => { if ((typeof (selector) === "string" && document.querySelector(selector) != null)) { callbackFunc(document.querySelector(selector)); if (doClear) return true; } else if (typeof (selector) === "function" && (selector() != null || (selector() || []).length > 0)) { callbackFunc(selector()[0]); if (doClear) return true; } }, time, true); } /** * * @param { * 回调函数, 需要返回是否, True: 结束、False: 相当于定时器 * callback return: * true = 倒计时 * false = 计时器 * } callback * @param { 周期,如: 200ms } period * @param { 立即执行 } now * @param { 次数, -1: Infinity } count */ function createStyleElement(css, className = '', type = "text/css") { const element = document.createElement("style"); if (className) { element.className = className const xclass = '.' + className.split(' ').join('.') element.dataset.xclass = xclass } element.setAttribute("type", type); element.appendChild(document.createTextNode(css)) return element }; (function () { "use strict"; const hostname = window.location.href; const CURRENT_LIST = "CurrentList"; const ELCONFIG = "ElConfig"; let ElConfig = {}; reloadAllConfig(); const globalStyle = ` #eliauk-container .arco-input-wrapper .arco-input.arco-input-size-mini { height: 20px; } #eliauk-container a, #eliauk-container abbr, #eliauk-container address, #eliauk-container blockquote, #eliauk-container caption, #eliauk-container cite, #eliauk-container code, #eliauk-container dd, #eliauk-container del, #eliauk-container dfn, #eliauk-container dl, #eliauk-container dt, #eliauk-container em, #eliauk-container fieldset, #eliauk-container form, #eliauk-container h1, #eliauk-container h2, #eliauk-container h3, #eliauk-container h4, #eliauk-container h5, #eliauk-container h6, #eliauk-container iframe, #eliauk-container img, #eliauk-container ins, #eliauk-container label, #eliauk-container legend, #eliauk-container li, #eliauk-container object, #eliauk-container ol, #eliauk-container p, #eliauk-container pre, #eliauk-container q, #eliauk-container small, #eliauk-container strong, #eliauk-container sub, #eliauk-container sup, #eliauk-container table, #eliauk-container tbody, #eliauk-container td, #eliauk-container tfoot, #eliauk-container th, #eliauk-container thead, #eliauk-container tr, #eliauk-container ul { border: 0; margin: 0; padding: 0; } #eliauk-container { font-family: HarmonyOS Sans SC, Inter, -apple-system, BlinkMacSystemFont, PingFang SC, Hiragino Sans GB, noto sans, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif; display: none; position: fixed; top: 3.9vw; right: 12.5vw; z-index: 999999; box-shadow: -2px 2px 5px rgb(0 0 0 / 30%); border-radius: var(--border-radius-medium); } /* 对话框 */ #eliauk-container .arco-modal { position: static; display: block; width: 360px; } #eliauk-container .arco-modal-header { border-bottom: none; } #eliauk-container .arco-modal-body { padding-top: 0px; overflow: visible; } #eliauk-container .arco-modal-body .arco-divider-horizontal.arco-divider-with-text:first-child { margin-top: 0; } #eliauk-container .arco-form-item { margin-bottom: 10px; } /* 折叠页相关 */ #eliauk-container .page-collapse { display: block; box-sizing: border-box; width: 100%; height: 100%; } #eliauk-container .page-one, #eliauk-container .page-two { padding: 0 2px 0 12px; overflow-y: scroll; } #eliauk-container .page { overflow: hidden; } #eliauk-container .page, #eliauk-container .page-one, #eliauk-container .page-two { height: 435px; opacity: 1; transition: all .3s; } #eliauk-container .page-collapse-btn svg { transition: all .3s; } #eliauk-container .page-collapse-btn-collapse svg { -webkit-transform: rotate(180deg); -moz-transform: rotate(180deg); -o-transform: rotate(180deg); -ms-transform: rotate(180deg); transform: rotate(180deg); } #eliauk-container .page-collapse+div, #eliauk-container .page-collapse.page-collapse-collapse { height: 0; opacity: 0; } #eliauk-container .page-collapse.page-collapse-collapse+div { height: 435px; opacity: 1; } #eliauk-container .page-collapse-btn { position: relative; left: 0; transition: left .2s; } /* 滑动输入框相关 */ #eliauk-container .eliauk-slider-context { min-height: 24px; display: inline-flex; justify-content: center; align-items: center; } #eliauk-container .eliauk-slider { -webkit-appearance: none; appearance: none; outline: none; /* 避免点选会有蓝线或虚线 */ width: 100%; height: 2px; border-radius: 2px; background: linear-gradient(to right, rgb(var(--primary-6)) 100%, var(--color-fill-3) 100%); cursor: pointer; } #eliauk-container .eliauk-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 12px; height: 12px; background: #fff; border: 2px solid rgb(var(--primary-6)); border-radius: 50%; transition: all 0.3s cubic-bezier(0.3, 1.3, 0.3, 1); } #eliauk-container .eliauk-slider::-webkit-slider-thumb:hover { box-shadow: 0 2px 5px #0000001a; transform: scale(1.16666667); } /* 输入框 */ #eliauk-container .arco-input-wrapper { padding: 0px; } #eliauk-container .arco-input-wrapper .arco-input { text-align: center; } /* 颜色输入框 */ #eliauk-container .color { border: none; outline: none; width: 100%; border-radius: 0; border-top-right-radius: var(--border-radius-small); border-bottom-right-radius: var(--border-radius-small); background-color: transparent; padding: 0; margin: 0; overflow: hidden; } #eliauk-container .color::-webkit-color-swatch-wrapper { padding: 0; margin: 0; } #eliauk-container .color::-webkit-color-swatch { border: none; } /* 预览区 */ #eliauk-container .context { text-align: left; } #eliauk-container .context div { background: ${data.scrollbar.background}; border-radius: ${data.scrollbar.radius}px; display: inline-block; } #eliauk-container .context .context-y { height: 100px; width: ${data.scrollbar.width}px; } #eliauk-container .context .context-x { height: ${data.scrollbar.height}px; width: 100px; } /* 折叠面板 */ #eliauk-container .arco-collapse-item .arco-collapse-item-content { /* display: none; */ height: 0; padding: 0; transition: all .2s; } #eliauk-container .arco-collapse-item-content-box { padding: 5px; height: 100%; box-sizing: border-box; } #eliauk-container .arco-collapse-item.arco-collapse-item-active .arco-collapse-item-content { display: block; height: 100px; } #eliauk-container .arco-collapse-item .arco-collapse-item-header .arco-collapse-item-header-title { font-weight: 500; } #rule-list-title-collapse { margin-bottom: 5px; } #rule-list-title-collapse .arco-collapse-item.arco-collapse-item-active .arco-collapse-item-content { height: 380px; } #rule-list-title-collapse:has(.arco-collapse-item.arco-collapse-item-active)+.arco-collapse { height: 0; opacity: 0; } /* 文本域 */ #eliauk-container .arco-textarea-wrapper { display: inline-flex; height: 100%; } #eliauk-container .arco-textarea::-webkit-scrollbar, #eliauk-container div::-webkit-scrollbar { width: 10px; background: transparent; } #eliauk-container .arco-textarea::-webkit-scrollbar-thumb, #eliauk-container div::-webkit-scrollbar-thumb { background: var(--color-fill-3) content-box; border: 2px solid transparent; border-radius: 5px; } `; // 添加 自定义的动画 const aniStyle = ` @keyframes ani_leftToright { 0% { transform: translateX(-32px); opacity: 0.2; } 20% { opacity: 0.5; } 30% { opacity: 0.8; } 100% { opacity: 1; } } /* ani */ @keyframes ani_bottomTotop { 0% { transform: translateY(32px); opacity: 0.2; } 20% { opacity: 0.5; } 30% { opacity: 0.8; } 100% { opacity: 1; } } @-webkit-keyframes ani_topTobuttom { 0% { transform: translateY(-32px); opacity: 0.2; } 20% { opacity: 0.5; } 30% { opacity: 0.8; } 100% { opacity: 1; } } @-webkit-keyframes ani_hideToShow { 0% { display:none; opacity: 0.2; } 20% { opacity: 0.5; } 30% { opacity: 0.8; } 100% { opacity: 1; } } @-webkit-keyframes ani_showToHide { 0% { display:none; opacity: 1; } 20% { opacity: 0.8; } 30% { opacity: 0.5; } 100% { opacity: 0.3; } } .aniDelete { transition: all 0.15s cubic-bezier(0.4, 0, 1, 1); opacity: 0.1; } `; const context = { flushFragment: new FlushDomFragment() } main(); function main() { reloadScrollbar(); // 注册菜单项 registerMenuCommand(); // 等待body加载完成 safeWaitFunc("body", () => { retryInterval(() => { if (!mountSettingModal()) return false; reloadNodeParam(); reloadRules(); reloadBasicSettingsPage(); reloadSolidPage(); addEventListenerAll(); return true; }, 200, true); // retryInterval(() => { // context.flushFragment.flush(); // debug("reload"); // return true; // }, 200, true); // debug("retry"); preloadGMStyle(); context.flushFragment.flush(); }) } function reloadAllConfig() { const res = GM_getValue(ELCONFIG); debug(res); if (res && (res !== 'undefined' && res !== 'null')) { try { data = JSON.parse(res); } catch (e) { data = res; } } else { data = DefaultConfig; debug("default", data); } } function reloadScrollbar() { debug(data.rule.config); const globalConfig = data.rule.config[data.rule.default]; const isCodeSetting = globalConfig && parseBoolean(globalConfig.enable); addCustomStyle(isCodeSetting); if (!isCodeSetting) { const { width, height, radius, background } = data.scrollbar; const style = ` ::-webkit-scrollbar{width:${width}px;height:${height}px;}::-webkit-scrollbar-thumb{border: 2px solid transparent;border-radius:${radius}px;background:${background} content-box;}::-webkit-scrollbar-track{box-shadow:none;} ` GM_addStyle(style); // context.flushFragment.insert(createStyleElement(style, "eliauk-custom-style"), 'head', { // isReload: true // }); } } function reloadNodeParam() { nodes = { scrollbar: { width: { comp: $one("#scrollbar-width"), text: $one("#scrollbar-width-text") }, height: { comp: $one("#scrollbar-height"), text: $one("#scrollbar-height-text") }, radius: { comp: $one("#scrollbar-radius"), text: $one("#scrollbar-radius-text") } }, color: { solid: { color: { comp: $one("#solid-color"), text: $one("#solid-color-text") } }, gradient: { color: { comp: $one("#gradient-color"), text: $one("#gradient-color-text") }, length: { text: $one("#gradient-lenght") }, step: { comp: $one("#gradient-step"), text: $one("#gradient-step-text") }, direction: { comp: $one("#gradient-direction"), text: $one("#gradient-direction-text") } } } } scrollbarY = $one("#eliauk-container .context .context-y"); scrollbarX = $one("#eliauk-container .context .context-x"); ruleTitles = $one("#rule-list-title-collapse .arco-textarea"); ruleConfig = $one("#rule-list-config-collapse"); } // 添加所有监听器 function addEventListenerAll() { // 渐变方向滑动输入事件 nodes.color.gradient.direction.comp.addEventListener("input", function () { // debug("input", this.value); nodes.color.gradient.direction.text.value = `${this.value}deg`; data.scrollbar.color.gradient.direction = this.value; reloadGradientPreviewBackground(); }) // 渐变位置滑动输入事件 nodes.color.gradient.step.comp.addEventListener("input", function () { // debug("input", this.value); let total = this.max - this.min; let effset = Math.round((this.value * 100) / total); nodes.color.gradient.step.text.value = `${effset}%`; const color = data.scrollbar.color.gradient.steps[this.value] ? data.scrollbar.color.gradient.steps[this.value] : data.scrollbar.color.default; nodes.color.gradient.color.comp.value = color; nodes.color.gradient.color.text.value = color; }) // 纯色颜色输入框事件 nodes.color.solid.color.comp.addEventListener('input', function () { // debug(this.value); nodes.color.solid.color.text.value = this.value; data.scrollbar.color.solid = this.value; resetPreviewBackground(this.value); }) // 渐变颜色输入框事件 nodes.color.gradient.color.comp.addEventListener('input', function () { // debug(this.value); nodes.color.gradient.color.text.value = this.value; const linear = nodes.color.gradient.step.comp.value; data.scrollbar.color.gradient.steps[linear] = this.value; reloadGradientPreviewBackground(); }); $all("#eliauk-container .close-button").forEach((element) => { element.addEventListener("click", closePanel); }); $one("#eliauk-container .confirm-button").addEventListener("click", function () { debug(data); GM_setValue(ELCONFIG, JSON.stringify(data)); setTimeout(function () { window.location.reload(); }, 200); }); // 按钮数组输入框 $all("#eliauk-container .arco-input-number-mode-button").forEach(ele => { const wrapper_input = $one(".arco-input-wrapper > .arco-input", ele); const prepend_button = $one(".arco-input-prepend > .arco-btn", ele); const append_button = $one(".arco-input-append > .arco-btn", ele); const max = Number(wrapper_input.max) || Infinity; const min = Number(wrapper_input.min) || -Infinity; const step = Number(wrapper_input.step) || 1; prepend_button.addEventListener("click", () => { if (Number(wrapper_input.value) > min) { wrapper_input.value = Number(wrapper_input.value) - step; wrapper_input.dispatchEvent(new Event('change')) } }) append_button.addEventListener("click", () => { if (Number(wrapper_input.value) < max) { wrapper_input.value = Number(wrapper_input.value) + step; wrapper_input.dispatchEvent(new Event('change')) } }) }) // 单选组 $all("#eliauk-container .arco-radio-group-button").forEach(group => { $all(".arco-radio-button", group).forEach(ele => { ele.addEventListener('click', function (e) { e.preventDefault(); $one(".arco-radio-checked", group).classList.remove("arco-radio-checked"); this.classList.add("arco-radio-checked"); group.dispatchEvent(new Event('select')); }) }) }) // 滑动输入条 $all("#eliauk-container .eliauk-slider").forEach(ele => { redrawSliderStyle(ele); ele.addEventListener("input", () => redrawSliderStyle(ele)); ele.addEventListener("mousewheel", function (e) { e.preventDefault(); const symbol = e.wheelDelta < 0 ? -1 : 1; const step = Number(ele.step) || 1; this.value = Number(this.value) + (symbol * step); this.dispatchEvent(new Event('input')); }) }); // 滚动条y方向宽度 nodes.scrollbar.width.comp.addEventListener("input", function () { scrollbarY.style.width = `${this.value}px`; data.scrollbar.width = this.value; nodes.scrollbar.width.text.value = this.value }) // 滚动条x方向高度 nodes.scrollbar.height.comp.addEventListener("input", function () { scrollbarX.style.height = `${this.value}px`; data.scrollbar.height = this.value; nodes.scrollbar.height.text.value = this.value; }) // 滚动条圆角值 nodes.scrollbar.radius.comp.addEventListener("input", function () { // debug("input", this.value); scrollbarX.style.borderRadius = `${this.value}px`; scrollbarY.style.borderRadius = `${this.value}px`; data.scrollbar.radius = this.value; nodes.scrollbar.radius.text.value = this.value }) // 基础、高级切换按钮 $one("#eliauk-container .page-collapse-btn").addEventListener("click", function () { // debug(this); // debug(this.classList.value); const aside = $one("#eliauk-container .page-collapse"); if (this.classList.contains("page-collapse-btn-collapse")) { this.classList.remove("page-collapse-btn-collapse"); aside.classList.remove("page-collapse-collapse"); $one("#page-title").innerText = "高级设置"; } else { this.classList.add("page-collapse-btn-collapse") aside.classList.add("page-collapse-collapse"); $one("#page-title").innerText = "基础设置"; } }) $all("#eliauk-container .arco-collapse").forEach(coll => { // 事件委派 coll.addEventListener("input", ev => { debug(ev); const $ev = ev || window.event; const target = $ev.target || $ev.srcElement; if (target.classList.contains("arco-textarea")) { debug(target); const titleComp = $one(`#rule-list-config-collapse .arco-collapse-item-header-title[data-v="${target.dataset.v}"]`, coll); if (!titleComp) return; const title = titleComp.innerText; debug(title, target.value); if (!data.rule.config[title]) { data.rule.config[title] = {}; } data.rule.config[title].style = target.value; } }) coll.addEventListener("click", ev => { const $ev = ev || window.event; const target = $ev.target || $ev.srcElement; // debug(target); if (isClickSwitch(target)) { arcoSwitchChange(target, coll); return; } if (isClickCollapseItemHeader(target)) { arcoCollapseItemHeaderClick(target, coll); return; } }) }); ruleTitles.addEventListener("change", () => { // debug(JSON.stringify(ruleTitles.value)); data.rule.titles = ruleTitles.value .split(";") .map(val => val.trim()) .filter(val => !!val); // debug(new RegExp(data.rule.titles[0]).test("https://.tbilibili.com")); }) $one(`#rule-list-title-collapse .arco-collapse-item.arco-collapse-item-active .arco-collapse-item-header`).addEventListener("click", function () { clearChilrenNodes(ruleConfig); // debug(title); const titles = [...data.rule.default, ...data.rule.titles]; titles.forEach(item => { const data_v = generateMixed(6); const text_value = data.rule.config[item]?.style || ""; ruleConfig.insertAdjacentHTML('beforeend', ` <div class="arco-collapse-item" data-v="${data_v}"> <div role="button" aria-disabled="false" aria-expanded="false" tabindex="0" class="arco-collapse-item-header arco-collapse-item-header-left" data-v="${data_v}"> <span class="arco-icon-hover arco-collapse-item-icon-hover"> <svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" class="arco-icon arco-icon-right arco-collapse-item-expand-icon" stroke-width="4" stroke-linecap="butt" stroke-linejoin="miter" data-v="${data_v}"> <path d="m16 39.513 15.556-15.557L16 8.4"></path> </svg> </span> <div class="arco-collapse-item-header-title" data-v="${data_v}">${item.trim()}</div> <div class="arco-collapse-item-header-extra"> <button type="button" role="switch" onchange="ruleConfigSwitch(this)" aria-checked="${!!data.rule.config[item]?.enable}" class="arco-switch arco-switch-type-circle arco-switch-small${!!data.rule.config[item]?.enable ? " arco-switch-checked" : " "}" data-v="${data_v}"> <span class="arco-switch-handle" data-v="${data_v}"> <span class="arco-switch-handle-icon" data-v="${data_v}"></span> </span> </button> </div> </div> <div role="region" class="arco-collapse-item-content"> <div class="arco-collapse-item-content-box"> <div class="arco-textarea-wrapper arco-textarea-scroll"> <textarea class="arco-textarea" style="resize: none; overflow: auto;" data-v="${data_v}">${text_value}</textarea> </div> </div> </div> </div> `); }); // debug(list); // $one("#rule-list-config-collapse"); }) } function mountSettingModal() { if (document.body === null) return false; if ($one("#eliauk-container") !== null) return true; const Container = document.createElement("div"); Container.id = "eliauk-container"; Container.innerHTML = ` <div class="arco-modal"> <div class="arco-modal-header"> <div class="arco-modal-title arco-modal-title-align-center"> <div class="aside-top"> <button type="button" class="page-collapse-btn-collapse arco-btn arco-btn-secondary arco-btn-shape-circle arco-btn-size-large arco-btn-status-normal page-collapse-btn"> <svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" class="arco-icon arco-icon-up" stroke-width="4" stroke-linecap="butt" stroke-linejoin="miter"> <path d="M39.6 30.557 24.043 15 8.487 30.557"></path> </svg> </button> </div> </div> <div tabindex="-1" role="button" aria-label="Close" class="close-button arco-modal-close-btn"> <span class="arco-icon-hover"> <svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" class="arco-icon arco-icon-close" stroke-width="4" stroke-linecap="butt" stroke-linejoin="miter"> <path d="M9.857 9.858 24 24m0 0 14.142 14.142M24 24 38.142 9.858M24 24 9.857 38.142"></path> </svg> </span> </div> </div> <div class="arco-modal-body"> <div class="arco-divider arco-divider-horizontal arco-divider-with-text"> <span id="page-title" class="arco-divider-text arco-divider-text-left">基础设置</span> </div> <div class="page"> <div class="page-one page-collapse page-collapse-collapse"> <div id="rule-list-title-collapse" class="arco-collapse"> <div class="arco-collapse-item arco-collapse-item-active" data-v="111"> <div role="button" aria-disabled="false" aria-expanded="true" tabindex="0" class="arco-collapse-item-header arco-collapse-item-header-left" data-v="111"> <span class="arco-icon-hover arco-collapse-item-icon-hover"> <svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" class="arco-icon arco-icon-right arco-collapse-item-expand-icon" stroke-width="4" stroke-linecap="butt" stroke-linejoin="miter" data-v="111"> <path d="m16 39.513 15.556-15.557L16 8.4"></path> </svg> </span> <div class="arco-collapse-item-header-title" data-v="111"> 域名列表 </div> </div> <div role="region" class="arco-collapse-item-content"> <div class="arco-collapse-item-content-box"> <div class="arco-textarea-wrapper arco-textarea-scroll"> <textarea class="arco-textarea" style="resize: none; overflow: auto;"></textarea> </div> </div> </div> </div> </div> <div id="rule-list-config-collapse" class="arco-collapse"></div> </div> <div class="page-two"> <form class="arco-form arco-form-layout-horizontal arco-form-size-mini"> <div class="arco-row arco-row-align-start arco-row-justify-start"> <div class="arco-col arco-col-24"> <div class="arco-row arco-row-nowrap arco-row-align-start arco-row-justify-start arco-form-item arco-form-item-layout-horizontal"> <div class="arco-col arco-form-item-label-col" style="flex: 0 0 110px"> <label class="arco-form-item-label">滚动条宽度(px)</label> </div> <div class="arco-col arco-form-item-wrapper-col"> <div class="arco-form-item-content-wrapper"> <div class="arco-form-item-content arco-form-item-content-flex"> <span class="arco-input-wrapper eliauk-input-number" style="flex: 0 0 60px;"> <input id="scrollbar-width-text" type="text" value="6" class="arco-input arco-input-size-mini" disabled /> </span> <div class="eliauk-slider-context" style="flex: 1; margin-left: 15px;"> <input id="scrollbar-width" type="range" value="6" min="0" max="30" step="1" class="eliauk-slider" /> </div> </div> </div> </div> </div> </div> <div class="arco-col arco-col-24"> <div class="arco-row arco-row-nowrap arco-row-align-start arco-row-justify-start arco-form-item arco-form-item-layout-horizontal"> <div class="arco-col arco-form-item-label-col" style="flex: 0 0 110px"> <label class="arco-form-item-label">滚动条高度(px)</label> </div> <div class="arco-col arco-form-item-wrapper-col"> <div class="arco-form-item-content-wrapper"> <div class="arco-form-item-content arco-form-item-content-flex"> <span class="arco-input-wrapper eliauk-input-number" style="flex: 0 0 60px;"> <input id="scrollbar-height-text" value="6" type="text" class="arco-input arco-input-size-mini" disabled /> </span> <div class="eliauk-slider-context" style="flex: 1; margin-left: 15px;"> <input id="scrollbar-height" type="range" value="6" min="0" max="30" step="1" class="eliauk-slider" /> </div> </div> </div> </div> </div> </div> <div class="arco-col arco-col-24"> <div class="arco-row arco-row-nowrap arco-row-align-start arco-row-justify-start arco-form-item arco-form-item-layout-horizontal"> <div class="arco-col arco-form-item-label-col" style="flex: 0 0 110px"> <label class="arco-form-item-label">滚动条弧度(px)</label> </div> <div class="arco-col arco-form-item-wrapper-col"> <div class="arco-form-item-content-wrapper"> <div class="arco-form-item-content arco-form-item-content-flex"> <span class="arco-input-wrapper eliauk-input-number" style="flex: 0 0 60px;"> <input id="scrollbar-radius-text" value="10" type="text" class="arco-input arco-input-size-mini" disabled /> </span> <div class="eliauk-slider-context" style="flex: 1; margin-left: 15px;"> <input id="scrollbar-radius" type="range" value="10" min="0" max="15" step="0.1" class="eliauk-slider" /> </div> </div> </div> </div> </div> </div> </div> <div class="arco-divider arco-divider-horizontal arco-divider-with-text"> <span class="arco-divider-text arco-divider-text-left">颜色</span> </div> <div style="margin-bottom: 10px;"> <span onselect="colorSelect(this)" class="arco-radio-group-button arco-radio-group-size-mini arco-radio-group-direction-horizontal"> <label class="arco-radio-button arco-radio-checked"> <input type="radio" class="arco-radio-target" value="SolidColor"> <span class="arco-radio-button-content">纯色</span> </label> <label class="arco-radio-button"> <input type="radio" class="arco-radio-target" value="GradientColor"> <span class="arco-radio-button-content">渐变色</span> </label> </span> </div> <div id="solid-color-page" class="arco-row arco-row-align-start arco-row-justify-start"> <div class="arco-col arco-col-24"> <div class="arco-row arco-row-nowrap arco-row-align-start arco-row-justify-start arco-form-item arco-form-item-layout-horizontal"> <div class="arco-col arco-form-item-label-col" style="flex: 0 0 110px"> <label class="arco-form-item-label">滚动条颜色(hex)</label> </div> <div class="arco-col arco-form-item-wrapper-col"> <div class="arco-form-item-content-wrapper"> <div class="arco-form-item-content arco-form-item-content-flex"> <span class="arco-input-outer arco-input-outer-size-mini arco-input-search"> <span class="arco-input-wrapper" style="flex: 0 0 90px;"> <input class="arco-input arco-input-size-mini" type="text" id="solid-color-text" value="#f2f3f5" disabled /> </span> <span class="arco-input-append" style="width:30px"> <input value="#f2f3f5" type="color" id="solid-color" class="color arco-btn-size-mini" /> </span> </span> </div> </div> </div> </div> </div> </div> <div id="gradient-color-page" class="arco-row arco-row-align-start arco-row-justify-start" style="display: none;"> <div class="arco-col arco-col-24"> <div class="arco-row arco-row-nowrap arco-row-align-start arco-row-justify-start arco-form-item arco-form-item-layout-horizontal"> <div class="arco-col arco-form-item-label-col" style="flex: 0 0 110px"> <label class="arco-form-item-label">滚动条渐变长度</label> </div> <div class="arco-col arco-form-item-wrapper-col"> <div class="arco-form-item-content-wrapper"> <div class="arco-form-item-content arco-form-item-content-flex"> <span style="flex: 0 0 90px" class="arco-input-outer arco-input-outer-size-mini arco-input-number arco-input-number-mode-button arco-input-number-size-mini"> <span class="arco-input-prepend"> <button type="button" class="arco-btn arco-btn-secondary arco-btn-shape-square arco-btn-size-mini arco-btn-status-normal arco-btn-only-icon arco-input-number-step-button"> <span class="arco-btn-icon"> <svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" class="arco-icon arco-icon-minus" stroke-width="4" stroke-linecap="butt" stroke-linejoin="miter"> <path d="M5 24h38"></path> </svg> </span> </button> </span> <span class="arco-input-wrapper"> <input id="gradient-lenght" onchange="gradientLenghtChange(this)" class="arco-input arco-input-size-mini" value="1" type="text" min="1" max="10" disabled /> </span> <span class="arco-input-append"> <button class="arco-btn arco-btn-secondary arco-btn-shape-square arco-btn-size-mini arco-btn-status-normal arco-btn-only-icon arco-input-number-step-button" type="button"> <span class="arco-btn-icon"> <svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" class="arco-icon arco-icon-plus" stroke-width="4" stroke-linecap="butt" stroke-linejoin="miter"> <path d="M5 24h38M24 5v38"></path> </svg> </span> </button> </span> </span> <span style="margin-left: 5px;" class="arco-input-outer arco-input-outer-size-mini arco-input-search"> <span class="arco-input-wrapper"> <input class="arco-input arco-input-size-mini" type="text" id="gradient-color-text" value="#f2f3f5" disabled /> </span> <span class="arco-input-append" style="width:30px"> <input value="#f2f3f5" type="color" id="gradient-color" class="color arco-btn-size-mini" /> </span> </span> </div> </div> </div> </div> </div> <div class="arco-col arco-col-24"> <div class="arco-row arco-row-nowrap arco-row-align-start arco-row-justify-start arco-form-item arco-form-item-layout-horizontal"> <div class="arco-col arco-form-item-label-col" style="flex: 0 0 110px"> <label class="arco-form-item-label">滚动条渐变位</label> </div> <div class="arco-col arco-form-item-wrapper-col"> <div class="arco-form-item-content-wrapper"> <div class="arco-form-item-content arco-form-item-content-flex"> <span class="arco-input-wrapper eliauk-input-number" style="flex: 0 0 60px;"> <input id="gradient-step-text" value="0%" type="text" class="arco-input arco-input-size-mini" disabled /> </span> <div class="eliauk-slider-context" style="flex: 1; margin-left: 15px;"> <input id="gradient-step" type="range" value="0" min="0" max="1" step="1" class="eliauk-slider" /> </div> </div> </div> </div> </div> </div> <div class="arco-col arco-col-24"> <div class="arco-row arco-row-nowrap arco-row-align-start arco-row-justify-start arco-form-item arco-form-item-layout-horizontal"> <div class="arco-col arco-form-item-label-col" style="flex: 0 0 110px"> <label class="arco-form-item-label">滚动条渐变方向</label> </div> <div class="arco-col arco-form-item-wrapper-col"> <div class="arco-form-item-content-wrapper"> <div class="arco-form-item-content arco-form-item-content-flex"> <span class="arco-input-wrapper eliauk-input-number" style="flex: 0 0 60px;"> <input id="gradient-direction-text" value="0deg" class="arco-input arco-input-size-mini" type="text" disabled /> </span> <div class="eliauk-slider-context" style="flex: 1; margin-left: 15px;"> <input id="gradient-direction" type="range" value="0" min="0" max="360" step="1" class="eliauk-slider" /> </div> </div> </div> </div> </div> </div> </div> </form> <div class="arco-divider arco-divider-horizontal arco-divider-with-text"> <span class="arco-divider-text arco-divider-text-left">预览</span> </div> <div class="context"> <div class="context-x"></div> <div class="context-y"></div> </div> </div> </div> </div> <div class="arco-modal-footer"> <button type="button" class="close-button arco-btn arco-btn-secondary arco-btn-shape-square arco-btn-size-mini arco-btn-status-normal"> 取消 </button> <button type="button" class="confirm-button arco-btn arco-btn-primary arco-btn-shape-square arco-btn-size-mini arco-btn-status-normal"> 确定 </button> </div> </div> `; try { document.body.appendChild(Container); } catch (e) { debug(e); } } function closePanel() { debug("触发取消按钮"); document.querySelector("#eliauk-container").style.display = "none"; } // 注册脚本菜单 function registerMenuCommand() { const currentList = GM_getValue(CURRENT_LIST, []); // 清除之前的 clearCommand(currentList); currentList.push(GM_registerMenuCommand(`⚙️网页美化设置`, () => { $one("#eliauk-container").style.display = "block"; })); currentList.push(GM_registerMenuCommand(`🔄脚本重置 - 修复脚本`, () => { GM_setValue(ELCONFIG, undefined); location.reload(); })) GM_setValue(CURRENT_LIST, currentList); } // 清除所有菜单项 function clearCommand(list) { while (list.length) { GM_unregisterMenuCommand(list.shift()); } } // 检查是否存在于名单中 返回配置 function getStyle(configs, url) { debug(configs); const conf = []; Object.entries(configs).forEach(([reg, config]) => { debug(reg, config); debug(new RegExp(reg), url) debug(new RegExp(reg).test(url), parseBoolean(config.enable)) if (new RegExp(reg).test(url) && parseBoolean(config.enable)) { conf.push(config.style); } }); const style = conf.join(" "); debug(conf); return style; } // 选择开关切换事件 function arcoSwitchChange(target, element) { // debug(target); const btn = $one(`.arco-switch[data-v="${target.dataset.v}"]`, element); if (!btn) return; if (btn.classList.contains("arco-switch-checked")) { btn.classList.remove("arco-switch-checked"); btn.setAttribute("aria-checked", false); } else { btn.classList.add("arco-switch-checked"); btn.setAttribute("aria-checked", true); } btn.dispatchEvent(new Event('change')); } function isClickSwitch(target) { return [ 'arco-switch', 'arco-switch-handle', 'arco-switch-handle-icon' ].some(item => target.classList.contains(item)); } function isClickCollapseItemHeader(target) { return [ 'arco-collapse-item-header', 'arco-collapse-item-header-title', 'arco-collapse-item-expand-icon' ].some(item => target.classList.contains(item)); } function arcoCollapseItemHeaderClick(target, coll) { const header = $one(`.arco-collapse-item[data-v="${target.dataset.v}"]`, coll) if (!header) return; const isActive = header.classList.contains("arco-collapse-item-active"); if (isActive) { header.classList.remove("arco-collapse-item-active"); } else { const active = $one(".arco-collapse-item.arco-collapse-item-active", coll); if (active) { active.classList.remove("arco-collapse-item-active"); } header.classList.add("arco-collapse-item-active"); } } // debug(data.rule.titles.join(";\n")); // 清除子节点 function clearChilrenNodes(ele) { var len = ele.childNodes.length; // 子元素的个数 for (var i = len - 1; i >= 0; i--) { // 从后往前 ele.removeChild(ele.childNodes[i]); // 从第一个元素开始删除 } } //生成n位数字字母混合字符串 function generateMixed(n) { const chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ]; let res = ""; for (let i = 0; i < n; i++) { const id = Math.floor(Math.random() * chars.length); res += chars[id]; } return res; } function preloadGMStyle() { function loadResource(resourceName) { const data = GM_getResourceText(resourceName) GM_addStyle(data); } loadResource("ArcoDesignStyle"); // 添加全局样式 GM_addStyle(globalStyle); } function addCustomStyle(isCodeSetting) { if (!isCodeSetting) { safeRemove("style[class='eliauk-user-style']"); } else { const customStyle = getStyle(data.rule.config, hostname) if (customStyle) { context.flushFragment.insert(createStyleElement(customStyle, "eliauk-user-style"), 'head', { isReload: true }) } } context.flushFragment.insert(createStyleElement(aniStyle, "eliauk-animation-style")) } })();