// ==UserScript== // @name CookieManager // @namespace https://github.com/WhiteSevs/TamperMonkeyScript // @version 2025.3.26 // @author WhiteSevs // @description 简单而强大的Cookie编辑器,允许您快速创建、编辑和删除Cookie // @license GPL-3.0-only // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAA/NJREFUeF7tWm1u4jAQjVHusfR3jMQNlp5ky0l2e5K2Jym9ARLO79JzEMgyKF5FqeN5YzuwQPoHqRl/zPObN5NxVHbnf+rO/c9GAEYG3DkCYwjcOQFGETxbCGitF1mWLeq6/qGUmtZ1PW1+t0qpN2PMn0uwcTAA5vP5tKqqp8bhJ8C5R2PMCrBLajIIAFprOs3fkp0eGfFaluVSMiaFbVIAQhy3Tlw1AA3dXyjGQ0/lagFoxO091PGrZkAq5wmEq2NASuevDgCB889HXVjleb6tqmraaASbHeq6ptpgm+f5cr1eb2PDyzdenAUawfsENuXM60VRvBydQ+oCWmJljHkE1go2EQOgtSbB86q9L54FAJIubMuyfAj2DhgoAmA2m1FlR+nO+6eUWm42m9c+IwREO9YYI9ojt7fuc9HkRVF8Uv0OLPLsq+0F82T/DQDCKs8bu1rrGgDxZELh5LKdTCYfPpah88MMkGy6WdwpghL6A054mQaMx/oBaOy3F2xS2ZtNg/SsqqqocrnrUAqRhBggTF0I8MlsYjUCAiCA/skc5CYaHACO/rZq42oDzpHQ55RyXWNRgWQZ0Ef/xvFlu4sjzBShPkPjXPtzDQwGIM/zB1edzjEG2n06I7aUZgFwpS3u1dVX6LSyg83zv8DiKgSWeABczkSUut82ZJun0h4iggaSJhEGuKq20FLXWRylaKm5ABkMAN/Efb0CbjNDCSiXJlkGeOL5GwuYk/TG4xDiyYFOrGEB8NXuVtCoe0M3Pb445jbDVZs0/rRhpegX7T4nEUFJB8erTX3iyTVJulkHFU4uW6EMEN/y9KFgGdPuFQAC2HuK3JtlKgCIbtF9f8ebom12euncV3DRfFxzlkvXEAM4eiL5OMbGp+Lc3rgMAAHQIM02QmOcZMb23hr7AEDoLwEgeRgIAOstuny1A0J/GACOagJnxKYu4UTiH6E/DAAZpipUQvsHRGlqhDb1Bm3Jd8ME9wrZQsgeGbFgt9u9h765nbN/gJ6+iAGxLDhX/wCNfXuwMANoAFC0OGOcU2TJRQkjImzp2x0vAsCCIA0F7lS4ig5RTu5do28OMQAtJiA3xHbd0P4B4ru1CfrKLAgAqR6E9A8knmdZFuS8WAS7mxI2MaT9AxSDYOejAZBqgqR/wHmPtr25eYJDoD1xbI3AbbL7PFTwXOskAaAljPQBxWBt7r6yWApg2z4ZAO2Kkb4RTtnmHsLxoEJIgjSFxX6/XxwOh5+Cj6L+LdF6Z/gY8kvy5AxwgdQG46S8nc/lm/9RY5U+j/uixid6uSk5lEE1IHYjlxp/FgZcyjlk3REABKVbthkZcMuni/g2MgBB6ZZt/gJwetZfo7objAAAAABJRU5ErkJggg== // @supportURL https://github.com/WhiteSevs/TamperMonkeyScript/issues // @match *://*/* // @require https://fastly.jsdelivr.net/gh/WhiteSevs/TamperMonkeyScript@86be74b83fca4fa47521cded28377b35e1d7d2ac/lib/CoverUMD/index.js // @require https://fastly.jsdelivr.net/npm/@whitesev/utils@2.6.4/dist/index.umd.js // @require https://fastly.jsdelivr.net/npm/@whitesev/domutils@1.5.1/dist/index.umd.js // @require https://fastly.jsdelivr.net/npm/@whitesev/pops@2.0.2/dist/index.umd.js // @require https://fastly.jsdelivr.net/npm/qmsg@1.3.0/dist/index.umd.js // @connect * // @grant GM_cookie // @grant GM_deleteValue // @grant GM_getValue // @grant GM_info // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_unregisterMenuCommand // @grant GM_xmlhttpRequest // @grant unsafeWindow // @run-at document-start // ==/UserScript== (function (Qmsg, DOMUtils, Utils, pops) { 'use strict'; var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value); var _a; var _GM_cookie = /* @__PURE__ */ (() => typeof GM_cookie != "undefined" ? GM_cookie : void 0)(); var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)(); var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)(); var _GM_info = /* @__PURE__ */ (() => typeof GM_info != "undefined" ? GM_info : void 0)(); var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)(); var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)(); var _GM_unregisterMenuCommand = /* @__PURE__ */ (() => typeof GM_unregisterMenuCommand != "undefined" ? GM_unregisterMenuCommand : void 0)(); var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)(); var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)(); var _monkeyWindow = /* @__PURE__ */ (() => window)(); const PanelSettingConfig = { /** Toast位置 */ qmsg_config_position: { key: "qmsg-config-position", defaultValue: "bottom" }, /** 最多显示的数量 */ qmsg_config_maxnums: { key: "qmsg-config-maxnums", defaultValue: 3 }, /** 逆序弹出 */ qmsg_config_showreverse: { key: "qmsg-config-showreverse", defaultValue: false } }; const _SCRIPT_NAME_ = "CookieManager"; const utils = Utils.noConflict(); const domUtils = DOMUtils.noConflict(); const __pops = pops; const log = new utils.Log( _GM_info, _unsafeWindow.console || _monkeyWindow.console ); const SCRIPT_NAME = ((_a = _GM_info == null ? void 0 : _GM_info.script) == null ? void 0 : _a.name) || _SCRIPT_NAME_; const DEBUG = false; log.config({ debug: DEBUG, logMaxCount: 1e3, autoClearConsole: true, tag: true }); Qmsg.config( Object.defineProperties( { html: true, autoClose: true, showClose: false }, { position: { get() { return PopsPanel.getValue( PanelSettingConfig.qmsg_config_position.key, PanelSettingConfig.qmsg_config_position.defaultValue ); } }, maxNums: { get() { return PopsPanel.getValue( PanelSettingConfig.qmsg_config_maxnums.key, PanelSettingConfig.qmsg_config_maxnums.defaultValue ); } }, showReverse: { get() { return PopsPanel.getValue( PanelSettingConfig.qmsg_config_showreverse.key, PanelSettingConfig.qmsg_config_showreverse.defaultValue ); } }, zIndex: { get() { let maxZIndex = Utils.getMaxZIndex(); let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex().zIndex; return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100; } } } ) ); __pops.GlobalConfig.setGlobalConfig({ zIndex: () => { let maxZIndex = Utils.getMaxZIndex(void 0, void 0, ($ele) => { var _a2; if ((_a2 = $ele == null ? void 0 : $ele.classList) == null ? void 0 : _a2.contains("qmsg-shadow-container")) { return false; } if (($ele == null ? void 0 : $ele.closest("qmsg")) && $ele.getRootNode() instanceof ShadowRoot) { return false; } }); let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex().zIndex; return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100; }, mask: { // 开启遮罩层 enable: true, // 取消点击遮罩层的事件 clickEvent: { toClose: false, toHide: false } } }); const GM_Menu = new utils.GM_Menu({ GM_getValue: _GM_getValue, GM_setValue: _GM_setValue, GM_registerMenuCommand: _GM_registerMenuCommand, GM_unregisterMenuCommand: _GM_unregisterMenuCommand }); const httpx = new utils.Httpx(_GM_xmlhttpRequest); httpx.interceptors.request.use((data) => { return data; }); httpx.interceptors.response.use(void 0, (data) => { log.error("拦截器-请求错误", data); if (data.type === "onabort") { Qmsg.warning("请求取消"); } else if (data.type === "onerror") { Qmsg.error("请求异常"); } else if (data.type === "ontimeout") { Qmsg.error("请求超时"); } else { Qmsg.error("其它错误"); } return data; }); httpx.config({ logDetails: DEBUG }); ({ Object: { defineProperty: _unsafeWindow.Object.defineProperty }, Function: { apply: _unsafeWindow.Function.prototype.apply, call: _unsafeWindow.Function.prototype.call }, Element: { appendChild: _unsafeWindow.Element.prototype.appendChild }, setTimeout: _unsafeWindow.setTimeout }); utils.addStyle.bind(utils); document.querySelector.bind(document); document.querySelectorAll.bind(document); const utilsCookieManager = new Utils.GM_Cookie(); const KEY = "GM_Panel"; const ATTRIBUTE_INIT = "data-init"; const ATTRIBUTE_KEY = "data-key"; const ATTRIBUTE_DEFAULT_VALUE = "data-default-value"; const ATTRIBUTE_INIT_MORE_VALUE = "data-init-more-value"; const PROPS_STORAGE_API = "data-storage-api"; const UISwitch = function(text, key, defaultValue, clickCallBack, description, afterAddToUListCallBack) { let result = { text, type: "switch", description, attributes: {}, props: {}, getValue() { return Boolean( this.props[PROPS_STORAGE_API].get(key, defaultValue) ); }, callback(event, __value) { let value = Boolean(__value); log.success(`${value ? "开启" : "关闭"} ${text}`); if (typeof clickCallBack === "function") { if (clickCallBack(event, value)) { return; } } this.props[PROPS_STORAGE_API].set(key, value); }, afterAddToUListCallBack }; Reflect.set(result.attributes, ATTRIBUTE_KEY, key); Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue); Reflect.set(result.props, PROPS_STORAGE_API, { get(key2, defaultValue2) { return PopsPanel.getValue(key2, defaultValue2); }, set(key2, value) { PopsPanel.setValue(key2, value); } }); return result; }; const UISelect = function(text, key, defaultValue, data, callback, description) { let selectData = []; if (typeof data === "function") { selectData = data(); } else { selectData = data; } let result = { text, type: "select", description, attributes: {}, props: {}, getValue() { return this.props[PROPS_STORAGE_API].get(key, defaultValue); }, callback(event, isSelectedValue, isSelectedText) { let value = isSelectedValue; log.info(`选择:${isSelectedText}`); this.props[PROPS_STORAGE_API].set(key, value); if (typeof callback === "function") { callback(event, value, isSelectedText); } }, data: selectData }; Reflect.set(result.attributes, ATTRIBUTE_KEY, key); Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue); Reflect.set(result.props, PROPS_STORAGE_API, { get(key2, defaultValue2) { return PopsPanel.getValue(key2, defaultValue2); }, set(key2, value) { PopsPanel.setValue(key2, value); } }); return result; }; const Component_Common = { id: "view-general", title: "通用", forms: [ { text: "Toast配置", type: "forms", forms: [ UISelect( "Toast位置", PanelSettingConfig.qmsg_config_position.key, PanelSettingConfig.qmsg_config_position.defaultValue, [ { value: "topleft", text: "左上角" }, { value: "top", text: "顶部" }, { value: "topright", text: "右上角" }, { value: "left", text: "左边" }, { value: "center", text: "中间" }, { value: "right", text: "右边" }, { value: "bottomleft", text: "左下角" }, { value: "bottom", text: "底部" }, { value: "bottomright", text: "右下角" } ], (event, isSelectValue, isSelectText) => { log.info("设置当前Qmsg弹出位置" + isSelectText); }, "Toast显示在页面九宫格的位置" ), UISelect( "最多显示的数量", PanelSettingConfig.qmsg_config_maxnums.key, PanelSettingConfig.qmsg_config_maxnums.defaultValue, [ { value: 1, text: "1" }, { value: 2, text: "2" }, { value: 3, text: "3" }, { value: 4, text: "4" }, { value: 5, text: "5" } ], void 0, "限制Toast显示的数量" ), UISwitch( "逆序弹出", PanelSettingConfig.qmsg_config_showreverse.key, PanelSettingConfig.qmsg_config_showreverse.defaultValue, void 0, "修改Toast弹出的顺序" ) ] } ] }; const PanelUISize = { /** * 一般设置界面的尺寸 */ setting: { get width() { return window.innerWidth < 550 ? "88vw" : "550px"; }, get height() { return window.innerHeight < 450 ? "70vh" : "450px"; } }, /** * 信息界面,一般用于提示信息之类 */ info: { get width() { return window.innerWidth < 350 ? "350px" : "350px"; }, get height() { return window.innerHeight < 250 ? "250px" : "250px"; } } }; const UIButton = function(text, description, buttonText, buttonIcon, buttonIsRightIcon, buttonIconIsLoading, buttonType, clickCallBack, afterAddToUListCallBack, disable) { let result = { text, type: "button", attributes: {}, description, buttonIcon, buttonIsRightIcon, buttonIconIsLoading, buttonType, buttonText, callback(event) { if (typeof clickCallBack === "function") { clickCallBack(event); } }, afterAddToUListCallBack }; Reflect.set(result.attributes, ATTRIBUTE_INIT, () => { result.disable = Boolean( disable ); }); return result; }; const UIInput = function(text, key, defaultValue, description, changeCallBack, placeholder = "", isNumber, isPassword) { let result = { text, type: "input", isNumber: Boolean(isNumber), isPassword: Boolean(isPassword), props: {}, attributes: {}, description, getValue() { return this.props[PROPS_STORAGE_API].get(key, defaultValue); }, callback(event, value) { this.props[PROPS_STORAGE_API].set(key, value); }, placeholder }; Reflect.set(result.attributes, ATTRIBUTE_KEY, key); Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue); Reflect.set(result.props, PROPS_STORAGE_API, { get(key2, defaultValue2) { return PopsPanel.getValue(key2, defaultValue2); }, set(key2, value) { PopsPanel.setValue(key2, value); } }); return result; }; const UITextArea = function(text, key, defaultValue, description, changeCallBack, placeholder = "", disabled) { let result = { text, type: "textarea", attributes: {}, props: {}, description, placeholder, disabled, getValue() { let value = this.props[PROPS_STORAGE_API].get(key, defaultValue); if (Array.isArray(value)) { return value.join("\n"); } return value; }, callback(event, value) { this.props[PROPS_STORAGE_API].set(key, value); } }; Reflect.set(result.attributes, ATTRIBUTE_KEY, key); Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue); Reflect.set(result.props, PROPS_STORAGE_API, { get(key2, defaultValue2) { return PopsPanel.getValue(key2, defaultValue2); }, set(key2, value) { PopsPanel.setValue(key2, value); } }); return result; }; class RuleEditView { constructor(option) { __publicField(this, "option"); this.option = option; } /** * 显示视图 */ async showView() { var _a2; let $dialog = __pops.confirm({ title: { text: this.option.title, position: "center" }, content: { text: ( /*html*/ `
` ), html: true }, btn: utils.assign( { ok: { callback: async () => { await submitSaveOption(); } } }, this.option.btn || {}, true ), mask: { enable: true }, drag: true, style: ( /*css*/ ` ${__pops.config.cssText.panelCSS} .rule-form-container { } .rule-form-container li{ display: flex; align-items: center; justify-content: space-between; padding: 5px 20px; gap: 10px; } .pops-panel-item-left-main-text{ max-width: 150px; } .pops-panel-item-right-text{ padding-left: 30px; } .pops-panel-item-right-text, .pops-panel-item-right-main-text{ text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } ${((_a2 = this.option) == null ? void 0 : _a2.style) ?? ""} ` ), width: typeof this.option.width === "function" ? this.option.width() : window.innerWidth > 500 ? "500px" : "88vw", height: typeof this.option.height === "function" ? this.option.height() : window.innerHeight > 500 ? "500px" : "80vh" }); let $form = $dialog.$shadowRoot.querySelector( ".rule-form-container" ); $dialog.$shadowRoot.querySelector( "input[type=submit]" ); let $ulist = $dialog.$shadowRoot.querySelector(".rule-form-ulist"); let view = await this.option.getView(await this.option.data()); $ulist.appendChild(view); const submitSaveOption = async () => { let result = await this.option.onsubmit($form, await this.option.data()); if (!result.success) { return; } $dialog.close(); await this.option.dialogCloseCallBack(true); }; } } class RuleFilterView { constructor(option) { __publicField(this, "option"); this.option = option; } showView() { let $alert = __pops.alert({ title: { text: this.option.title, position: "center" }, content: { text: ( /*html*/ `
` ) }, btn: { ok: { text: "关闭", type: "default" } }, mask: { enable: true }, width: window.innerWidth > 500 ? "350px" : "80vw", height: window.innerHeight > 500 ? "300px" : "70vh", style: ( /*css*/ ` .filter-container{ height: 100%; display: flex; flex-direction: column; gap: 20px; } .filter-container button{ text-wrap: wrap; padding: 8px; height: auto; text-align: left; } ` ) }); let $filterContainer = $alert.$shadowRoot.querySelector(".filter-container"); let $fragment = document.createDocumentFragment(); this.option.filterOption.forEach((filterOption) => { let $button = document.createElement("button"); $button.innerText = filterOption.name; let execFilterAndCloseDialog = async () => { let allRuleInfo = await this.option.getAllRuleInfo(); allRuleInfo.forEach(async (ruleInfo) => { let filterResult = await filterOption.filterCallBack(ruleInfo.data); if (!filterResult) { domUtils.hide(ruleInfo.$el, false); } else { domUtils.show(ruleInfo.$el, false); } }); if (typeof this.option.execFilterCallBack === "function") { await this.option.execFilterCallBack(); } $alert.close(); }; domUtils.on($button, "click", async (event) => { utils.preventEvent(event); if (typeof filterOption.callback === "function") { let result = await filterOption.callback( event, execFilterAndCloseDialog ); if (!result) { return; } } await execFilterAndCloseDialog(); }); $fragment.appendChild($button); }); $filterContainer.appendChild($fragment); } } class RuleView { constructor(option) { __publicField(this, "option"); this.option = option; } /** * 显示视图 * @param filterCallBack 返回值为false隐藏,true则不隐藏(不处理) */ async showView(filterCallBack) { var _a2, _b, _c, _d, _e, _f, _g, _h, _i; let $popsConfirm = __pops.confirm({ title: { text: this.option.title, position: "center" }, content: { text: ( /*html*/ `
` ), html: true }, btn: { merge: true, reverse: false, position: "space-between", ok: { enable: ((_c = (_b = (_a2 = this.option) == null ? void 0 : _a2.bottomControls) == null ? void 0 : _b.add) == null ? void 0 : _c.enable) || true, type: "primary", text: "添加", callback: async (event) => { this.showEditView( false, await this.option.getAddData(), $popsConfirm.$shadowRoot ); } }, close: { enable: true, callback(event) { $popsConfirm.close(); } }, cancel: { enable: ((_f = (_e = (_d = this.option) == null ? void 0 : _d.bottomControls) == null ? void 0 : _e.filter) == null ? void 0 : _f.enable) || false, type: "default", text: "过滤", callback: (details, event) => { var _a3, _b2, _c2, _d2, _e2, _f2, _g2; if (typeof ((_c2 = (_b2 = (_a3 = this.option) == null ? void 0 : _a3.bottomControls) == null ? void 0 : _b2.filter) == null ? void 0 : _c2.callback) === "function") { this.option.bottomControls.filter.callback(); } let getAllRuleElement = () => { return Array.from( $popsConfirm.$shadowRoot.querySelectorAll( ".rule-view-container .rule-item" ) ); }; let $button = event.target.closest(".pops-confirm-btn").querySelector(".pops-confirm-btn-cancel span"); if (domUtils.text($button).includes("取消")) { getAllRuleElement().forEach(($el) => { domUtils.show($el, false); }); domUtils.text($button, "过滤"); } else { let ruleFilterView = new RuleFilterView({ title: ((_e2 = (_d2 = this.option.bottomControls) == null ? void 0 : _d2.filter) == null ? void 0 : _e2.title) ?? "过滤规则", filterOption: ((_g2 = (_f2 = this.option.bottomControls) == null ? void 0 : _f2.filter) == null ? void 0 : _g2.option) || [], execFilterCallBack() { domUtils.text($button, "取消过滤"); }, getAllRuleInfo: () => { return getAllRuleElement().map(($el) => { return { data: this.parseRuleItemElement($el).data, $el }; }); } }); ruleFilterView.showView(); } } }, other: { enable: ((_i = (_h = (_g = this.option) == null ? void 0 : _g.bottomControls) == null ? void 0 : _h.clear) == null ? void 0 : _i.enable) || true, type: "xiaomi-primary", text: `清空所有(${(await this.option.data()).length})`, callback: (event) => { let $askDialog = __pops.confirm({ title: { text: "提示", position: "center" }, content: { text: "确定清空所有的数据?", html: false }, btn: { ok: { enable: true, callback: async (popsEvent) => { var _a3, _b2, _c2; log.success("清空所有"); if (typeof ((_c2 = (_b2 = (_a3 = this.option) == null ? void 0 : _a3.bottomControls) == null ? void 0 : _b2.clear) == null ? void 0 : _c2.callback) === "function") { this.option.bottomControls.clear.callback(); } let data = await this.option.data(); if (data.length) { Qmsg.error("清理失败"); return; } else { Qmsg.success("清理成功"); } await this.updateDeleteAllBtnText($popsConfirm.$shadowRoot); this.clearContent($popsConfirm.$shadowRoot); $askDialog.close(); } }, cancel: { text: "取消", enable: true } }, mask: { enable: true }, width: "300px", height: "200px" }); } } }, mask: { enable: true }, drag: true, width: window.innerWidth > 500 ? "500px" : "88vw", height: window.innerHeight > 500 ? "500px" : "80vh", style: ( /*css*/ ` ${__pops.config.cssText.panelCSS} .rule-item{ display: flex; align-items: center; line-height: normal; font-size: 16px; padding: 4px 8px; gap: 8px; } .rule-name{ flex: 1; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } .rule-controls{ display: flex; align-items: center; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; gap: 8px; padding: 0px; } .rule-controls-enable{ } .rule-controls-edit{ } .rule-controls-delete{ } .rule-controls-edit, .rule-controls-delete{ width: 16px; height: 16px; cursor: pointer; } ` ) }); let allData = await this.option.data(); let changeButtonText = false; for (let index = 0; index < allData.length; index++) { let item = allData[index]; let $ruleItemList = await this.appendRuleItemElement( $popsConfirm.$shadowRoot, item ); let flag = typeof filterCallBack === "function" ? filterCallBack(item) : true; if (!flag) { changeButtonText = true; $ruleItemList.forEach(($el) => { domUtils.hide($el, false); }); } } if (changeButtonText) { let $button = $popsConfirm.$shadowRoot.querySelector( ".pops-confirm-btn-cancel span" ); domUtils.text($button, "取消过滤"); } } /** * 显示编辑视图 * @param isEdit 是否是编辑状态 * @param editData 编辑的数据 * @param $parentShadowRoot (可选)关闭弹窗后对ShadowRoot进行操作 * @param $editRuleItemElement (可选)关闭弹窗后对规则行进行更新数据 * @param updateDataCallBack (可选)关闭添加/编辑弹窗的回调(不更新数据) * @param submitCallBack (可选)添加/修改提交的回调 */ showEditView(isEdit, editData, $parentShadowRoot, $editRuleItemElement, updateDataCallBack, submitCallBack) { let dialogCloseCallBack = async (isSubmit) => { if (isSubmit) { if (typeof submitCallBack === "function") { let newData = await this.option.getData(editData); submitCallBack(newData); } } else { if (!isEdit) { await this.option.deleteData(editData); } if (typeof updateDataCallBack === "function") { let newData = await this.option.getData(editData); updateDataCallBack(newData); } } }; let editView = new RuleEditView({ title: isEdit ? "编辑" : "添加", data: () => { return editData; }, dialogCloseCallBack, getView: async (data) => { return await this.option.itemControls.edit.getView(data, isEdit); }, btn: { ok: { enable: true, text: isEdit ? "修改" : "添加" }, cancel: { callback: async (detail, event) => { detail.close(); await dialogCloseCallBack(false); } }, close: { callback: async (detail, event) => { detail.close(); await dialogCloseCallBack(false); } } }, onsubmit: async ($form, data) => { let result = await this.option.itemControls.edit.onsubmit( $form, isEdit, data ); if (result.success) { if (isEdit) { Qmsg.success("修改成功"); $parentShadowRoot && await this.updateRuleItemElement( result.data, $editRuleItemElement, $parentShadowRoot ); } else { $parentShadowRoot && await this.appendRuleItemElement( $parentShadowRoot, result.data ); } } else { if (isEdit) { Qmsg.error("修改失败"); } } return result; }, style: this.option.itemControls.edit.style, width: this.option.itemControls.edit.width, height: this.option.itemControls.edit.height }); editView.showView(); } /** * 解析弹窗内的各个元素 */ parseViewElement($shadowRoot) { let $container = $shadowRoot.querySelector( ".rule-view-container" ); let $deleteBtn = $shadowRoot.querySelector( ".pops-confirm-btn button.pops-confirm-btn-other" ); return { /** 容器 */ $container, /** 左下角的清空按钮 */ $deleteBtn }; } /** * 解析每一项的元素 */ parseRuleItemElement($ruleElement) { let $enable = $ruleElement.querySelector( ".rule-controls-enable" ); let $enableSwitch = $enable.querySelector(".pops-panel-switch"); let $enableSwitchInput = $enable.querySelector( ".pops-panel-switch__input" ); let $enableSwitchCore = $enable.querySelector( ".pops-panel-switch__core" ); let $edit = $ruleElement.querySelector(".rule-controls-edit"); let $delete = $ruleElement.querySelector( ".rule-controls-delete" ); return { /** 启用开关 */ $enable, /** 启用开关的container */ $enableSwitch, /** 启用开关的input */ $enableSwitchInput, /** 启用开关的core */ $enableSwitchCore, /** 编辑按钮 */ $edit, /** 删除按钮 */ $delete, /** 存储在元素上的数据 */ data: Reflect.get($ruleElement, "data-rule") }; } /** * 创建一条规则元素 */ async createRuleItemElement(data, $shadowRoot) { let name = await this.option.getDataItemName(data); let $ruleItem = domUtils.createElement("div", { className: "rule-item", innerHTML: ( /*html*/ `
${name}
${__pops.config.iconSVG.edit}
${__pops.config.iconSVG.delete}
` ) }); Reflect.set($ruleItem, "data-rule", data); let switchCheckedClassName = "pops-panel-switch-is-checked"; const { $enable, $enableSwitch, $enableSwitchCore, $enableSwitchInput, $delete, $edit } = this.parseRuleItemElement($ruleItem); if (this.option.itemControls.enable.enable) { domUtils.on($enableSwitchCore, "click", async (event) => { let isChecked = false; if ($enableSwitch.classList.contains(switchCheckedClassName)) { $enableSwitch.classList.remove(switchCheckedClassName); isChecked = false; } else { $enableSwitch.classList.add(switchCheckedClassName); isChecked = true; } $enableSwitchInput.checked = isChecked; await this.option.itemControls.enable.callback(data, isChecked); }); if (await this.option.itemControls.enable.getEnable(data)) { $enableSwitch.classList.add(switchCheckedClassName); } } else { $enable.remove(); } if (this.option.itemControls.edit.enable) { domUtils.on($edit, "click", (event) => { utils.preventEvent(event); this.showEditView(true, data, $shadowRoot, $ruleItem, (newData) => { data = null; data = newData; }); }); } else { $edit.remove(); } if (this.option.itemControls.delete.enable) { domUtils.on($delete, "click", (event) => { utils.preventEvent(event); let $askDialog = __pops.confirm({ title: { text: "提示", position: "center" }, content: { text: "确定删除该条数据?", html: false }, btn: { ok: { enable: true, callback: async (popsEvent) => { log.success("删除数据"); let flag = await this.option.itemControls.delete.deleteCallBack( data ); if (flag) { Qmsg.success("成功删除该数据"); $ruleItem.remove(); await this.updateDeleteAllBtnText($shadowRoot); $askDialog.close(); } else { Qmsg.error("删除该数据失败"); } } }, cancel: { text: "取消", enable: true } }, mask: { enable: true }, width: "300px", height: "200px" }); }); } else { $delete.remove(); } return $ruleItem; } /** * 添加一个规则元素 */ async appendRuleItemElement($shadowRoot, data) { let { $container } = this.parseViewElement($shadowRoot); let $ruleItem = []; let iteratorData = Array.isArray(data) ? data : [data]; for (let index = 0; index < iteratorData.length; index++) { let item = iteratorData[index]; let $item = await this.createRuleItemElement(item, $shadowRoot); $container.appendChild($item); $ruleItem.push($item); } await this.updateDeleteAllBtnText($shadowRoot); return $ruleItem; } /** * 更新弹窗内容的元素 */ async updateRuleContaienrElement($shadowRoot) { this.clearContent($shadowRoot); const { $container } = this.parseViewElement($shadowRoot); let data = await this.option.data(); await this.appendRuleItemElement($shadowRoot, data); await this.updateDeleteAllBtnText($shadowRoot); } /** * 更新规则元素 */ async updateRuleItemElement(data, $oldRuleItem, $shadowRoot) { let $newRuleItem = await this.createRuleItemElement(data, $shadowRoot); $oldRuleItem.after($newRuleItem); $oldRuleItem.remove(); } /** * 清空内容 */ clearContent($shadowRoot) { const { $container } = this.parseViewElement($shadowRoot); domUtils.html($container, ""); } /** * 设置删除按钮的文字 */ setDeleteBtnText($shadowRoot, text, isHTML = false) { const { $deleteBtn } = this.parseViewElement($shadowRoot); if (isHTML) { domUtils.html($deleteBtn, text); } else { domUtils.text($deleteBtn, text); } } /** * 更新【清空所有】的按钮的文字 * @param $shadowRoot */ async updateDeleteAllBtnText($shadowRoot) { let data = await this.option.data(); this.setDeleteBtnText($shadowRoot, `清空所有(${data.length})`); } } const CookieRule = { $key: { STORAGE_KEY: "cookie-rule" }, $data: { /** 规则数据 */ ruleData: [] }, /** 初始化数据 */ init() { this.$data.ruleData = []; let allData = this.getData(); allData.forEach((data) => { if (!data.enable) { return; } let url = window.location.href; let ruleUrl = data.data.url; let enableRegExpToMatchUrl = data.data.enableRegExpToMatchUrl; if (enableRegExpToMatchUrl) { let regExpUrl = new RegExp(ruleUrl, "i"); if (!regExpUrl.test(url)) { return; } } else { if (!url.includes(ruleUrl)) { return; } } this.$data.ruleData.push(data); }); }, /** * 显示视图 */ showView() { let popsPanelContentUtils = __pops.config.panelHandleContentUtils(); function generateStorageApi(data, handler) { return { get(key, defaultValue) { return Reflect.get(data, key) ?? defaultValue; }, set(key, value) { Reflect.set(data, key, value); } }; } let ruleView = new RuleView({ title: "Cookie规则", data: () => { return this.getData(); }, getAddData: () => { return this.getTemplateData(); }, getDataItemName: (data) => { return data["name"]; }, updateData: (data) => { return this.updateData(data); }, deleteData: (data) => { return this.deleteData(data); }, getData: (data) => { let allData = this.getData(); let findValue = allData.find((item) => item.uuid === data.uuid); return findValue ?? data; }, itemControls: { enable: { enable: true, getEnable(data) { return data.enable; }, callback: (data, enable) => { data.enable = enable; this.updateData(data); } }, edit: { enable: true, getView: (data, isEdit) => { let $fragment = document.createDocumentFragment(); let templateData = this.getTemplateData(); if (!isEdit) { data = templateData; } let enable_template = UISwitch( "启用", "enable", templateData.enable ); Reflect.set( enable_template.props, PROPS_STORAGE_API, generateStorageApi(data) ); let $enable = popsPanelContentUtils.createSectionContainerItem_switch( enable_template ); let name_template = UIInput( "规则名称", "name", "", templateData.name, void 0, "必填" ); Reflect.set( name_template.props, PROPS_STORAGE_API, generateStorageApi(data) ); let $name = popsPanelContentUtils.createSectionContainerItem_input( name_template ); let url_template = UIInput( "网址", "url", templateData.data.url, "用于执行该规则的网址", void 0, "必填" ); Reflect.set( url_template.props, PROPS_STORAGE_API, generateStorageApi(data.data) ); let $url = popsPanelContentUtils.createSectionContainerItem_input( url_template ); let enableRegExpToMatchUrl_template = UISwitch( "启用正则匹配网址", "enableRegExpToMatchUrl", templateData.data.enableRegExpToMatchUrl ); Reflect.set( enableRegExpToMatchUrl_template.props, PROPS_STORAGE_API, generateStorageApi(data.data) ); let $enableRegExpToMatchUrl = popsPanelContentUtils.createSectionContainerItem_switch( enableRegExpToMatchUrl_template ); let cookieName_template = UIInput( "Cookie名称", "cookieName", templateData.data.cookieName, "用于匹配执行操作的Cookie名", void 0, "必填" ); Reflect.set( cookieName_template.props, PROPS_STORAGE_API, generateStorageApi(data.data) ); let $cookieName = popsPanelContentUtils.createSectionContainerItem_input( cookieName_template ); let enableRegExpToMatchCookieName_template = UISwitch( "启用正则匹配Cookie名称", "enableRegExpToMatchCookieName", templateData.data.enableRegExpToMatchCookieName ); Reflect.set( enableRegExpToMatchCookieName_template.props, PROPS_STORAGE_API, generateStorageApi(data.data) ); let $enableRegExpToMatchCookieName = popsPanelContentUtils.createSectionContainerItem_switch( enableRegExpToMatchCookieName_template ); let operationMode_template = UISelect( "操作模式", "operationMode", templateData.data.operationMode, [ { value: "delete", text: "删除Cookie" }, { value: "extended", text: "自动延长Cookie有效期30天" }, { value: "extended-90", text: "自动延长Cookie有效期90天" }, { value: "extended-180", text: "自动延长Cookie有效期180天" }, { value: "extended-360", text: "自动延长Cookie有效期360天" } ] ); Reflect.set( operationMode_template.props, PROPS_STORAGE_API, generateStorageApi(data.data) ); let $operationMode = popsPanelContentUtils.createSectionContainerItem_select( operationMode_template ); let remark_template = UITextArea( "备注", "remark", templateData.data.remark ); Reflect.set( remark_template.props, PROPS_STORAGE_API, generateStorageApi(data.data) ); let $remark = popsPanelContentUtils.createSectionContainerItem_textarea( remark_template ); $fragment.append( $enable, $name, $url, $enableRegExpToMatchUrl, $cookieName, $enableRegExpToMatchCookieName, $operationMode, $remark ); return $fragment; }, onsubmit: ($form, isEdit, editData) => { let $ulist_li = $form.querySelectorAll( ".rule-form-ulist > li" ); let data = this.getTemplateData(); if (isEdit) { data.uuid = editData.uuid; } try { $ulist_li.forEach(($li) => { let formConfig = Reflect.get($li, "__formConfig__"); let attrs = Reflect.get(formConfig, "attributes"); let storageApi = Reflect.get($li, PROPS_STORAGE_API); let key = Reflect.get(attrs, ATTRIBUTE_KEY); let defaultValue = Reflect.get(attrs, ATTRIBUTE_DEFAULT_VALUE); let value = storageApi.get(key, defaultValue); if (Reflect.has(data, key)) { Reflect.set(data, key, value); } else if (Reflect.has(data.data, key)) { Reflect.set(data.data, key, value); } else { log.error(`${key}不在数据中`); } }); if (data.name.trim() === "") { Qmsg.error("规则名称不能为空"); return { success: false, data }; } if (data.data.url.trim() === "") { Qmsg.error("网址不能为空"); return { success: false, data }; } if (data.data.cookieName.trim() === "") { Qmsg.error("Cookie名称不能为空"); return { success: false, data }; } if (isEdit) { return { success: this.updateData(data), data }; } else { return { success: this.addData(data), data }; } } catch (error) { log.error(error); return { success: false, data }; } finally { this.init(); } }, style: ( /*css*/ ` .pops-panel-textarea textarea{ height: 150px; } .pops-panel-item-left-desc-text{ line-height: normal; margin-top: 6px; font-size: 0.8em; color: rgb(108, 108, 108); max-width: 100px; } ` ) }, delete: { enable: true, deleteCallBack: (data) => { return this.deleteData(data); } } } }); ruleView.showView(); }, /** * 获取模板数据 */ getTemplateData() { return { uuid: utils.generateUUID(), enable: true, name: "", data: { url: "", enableRegExpToMatchUrl: false, cookieName: "", enableRegExpToMatchCookieName: false, operationMode: "delete", remark: "" } }; }, /** * 获取数据 */ getData() { return _GM_getValue(this.$key.STORAGE_KEY, []); }, /** * 设置数据 * @param data */ setData(data) { _GM_setValue(this.$key.STORAGE_KEY, data); }, /** * 添加数据 * @param data */ addData(data) { let localData = this.getData(); let findIndex = localData.findIndex((item) => item.uuid == data.uuid); if (findIndex === -1) { localData.push(data); _GM_setValue(this.$key.STORAGE_KEY, localData); return true; } else { return false; } }, /** * 更新数据 * @param data */ updateData(data) { let localData = this.getData(); let index = localData.findIndex((item) => item.uuid == data.uuid); let updateFlag = false; if (index !== -1) { updateFlag = true; localData[index] = data; } this.setData(localData); return updateFlag; }, /** * 删除数据 * @param data */ deleteData(data) { let localData = this.getData(); let index = localData.findIndex((item) => item.uuid == data.uuid); let deleteFlag = false; if (index !== -1) { deleteFlag = true; localData.splice(index, 1); } this.setData(localData); return deleteFlag; }, /** * 清空数据 */ clearData() { _GM_deleteValue(this.$key.STORAGE_KEY); }, /** * 导出规则 */ exportRule(fileName = "rule.json") { let allRule = this.getData(); let blob = new Blob([JSON.stringify(allRule, null, 4)]); let blobUrl = window.URL.createObjectURL(blob); let $a = domUtils.createElement("a"); $a.href = blobUrl; $a.download = fileName; $a.click(); setTimeout(() => { window.URL.revokeObjectURL(blobUrl); }, 1500); }, /** * 导入规则 */ importRule() { let $alert = __pops.alert({ title: { text: "请选择导入方式", position: "center" }, content: { text: ( /*html*/ `
本地导入
网络导入
` ), html: true }, width: PanelUISize.info.width, height: PanelUISize.info.height, style: ( /*css*/ ` .import-mode{ display: inline-block; margin: 10px; padding: 10px; border: 1px solid #ccc; border-radius: 5px; cursor: pointer; } ` ) }); let $local = $alert.$shadowRoot.querySelector( ".import-mode[data-mode='local']" ); let $network = $alert.$shadowRoot.querySelector( ".import-mode[data-mode='network']" ); domUtils.on($local, "click", (event) => { utils.preventEvent(event); $alert.close(); let $input = domUtils.createElement("input", { type: "file", accept: ".json" }); domUtils.on($input, ["propertychange", "input"], (event2) => { var _a2; if (!((_a2 = $input.files) == null ? void 0 : _a2.length)) { return; } let uploadFile = $input.files[0]; let fileReader = new FileReader(); fileReader.onload = () => { let data = utils.toJSON(fileReader.result); if (!Array.isArray(data)) { log.error("不是正确的规则文件", data); Qmsg.error("不是正确的规则文件"); return; } this.setData(data); Qmsg.success(`成功导入 ${data.length}条规则`); }; fileReader.readAsText(uploadFile, "UTF-8"); }); $input.click(); }); domUtils.on($network, "click", (event) => { utils.preventEvent(event); $alert.close(); __pops.prompt({ title: { text: "网络导入", position: "center" }, content: { text: "", placeholder: "url", focus: true }, btn: { ok: { callback: async (eventDetails, event2) => { let url = eventDetails.text; if (utils.isNull(url)) { Qmsg.error("请填入完整的url"); return; } let response = await httpx.get(url); if (!response.status) { return; } let data = utils.toJSON(response.data.responseText); if (!Array.isArray(data)) { log.error("不是正确的规则文件", response, data); Qmsg.error("不是正确的规则文件"); return; } this.setData(data); eventDetails.close(); Qmsg.success(`成功导入 ${data.length}条规则`); } } }, width: PanelUISize.info.width, height: "auto" }); }); } }; const Component_Rule = { id: "view-rule", title: "规则", headerTitle: "Cookie操作规则", forms: [ { type: "forms", text: "", forms: [ UIButton( "自定义规则", "操作Cookie的规则", "管理", void 0, false, false, "default", () => { CookieRule.showView(); } ) ] }, { type: "forms", text: "", forms: [ UIButton( "数据导入", "导入自定义规则数据", "导入", void 0, false, false, "primary", () => { CookieRule.importRule(); } ), UIButton( "数据导出", "导出自定义规则数据", "导出", void 0, false, false, "primary", () => { CookieRule.exportRule("CookieManagerRule.json"); } ) ] } ] }; const PopsPanel = { /** 数据 */ $data: { __data: null, __oneSuccessExecMenu: null, __onceExec: null, __listenData: null, /** * 菜单项的默认值 */ get data() { if (PopsPanel.$data.__data == null) { PopsPanel.$data.__data = new utils.Dictionary(); } return PopsPanel.$data.__data; }, /** * 成功只执行了一次的项 */ get oneSuccessExecMenu() { if (PopsPanel.$data.__oneSuccessExecMenu == null) { PopsPanel.$data.__oneSuccessExecMenu = new utils.Dictionary(); } return PopsPanel.$data.__oneSuccessExecMenu; }, /** * 成功只执行了一次的项 */ get onceExec() { if (PopsPanel.$data.__onceExec == null) { PopsPanel.$data.__onceExec = new utils.Dictionary(); } return PopsPanel.$data.__onceExec; }, /** 脚本名,一般用在设置的标题上 */ get scriptName() { return SCRIPT_NAME; }, /** 菜单项的总值在本地数据配置的键名 */ key: KEY, /** 菜单项在attributes上配置的菜单键 */ attributeKeyName: ATTRIBUTE_KEY, /** 菜单项在attributes上配置的菜单默认值 */ attributeDefaultValueName: ATTRIBUTE_DEFAULT_VALUE }, /** 监听器 */ $listener: { /** * 值改变的监听器 */ get listenData() { if (PopsPanel.$data.__listenData == null) { PopsPanel.$data.__listenData = new utils.Dictionary(); } return PopsPanel.$data.__listenData; } }, init() { let contentConfigList = this.getPanelContentConfig(); this.initPanelConfigDefaultValue([...contentConfigList]); this.registerMenu(); }, /** 判断是否是顶层窗口 */ isTopWindow() { return _unsafeWindow.top === _unsafeWindow.self; }, /** 初始化进行注册油猴菜单 */ registerMenu() { if (!this.isTopWindow()) { return; } GM_Menu.add([ { key: "show_pops_panel_setting", text: "⚙ 设置", autoReload: false, isStoreValue: false, showText(text) { return text; }, callback: () => { this.showPanel(); } } ]); }, /** 初始化菜单项的默认值保存到本地数据中 */ initPanelConfigDefaultValue(contentConfigList) { let that = this; function initDefaultValue(config) { if (!config.attributes) { return; } let needInitConfig = {}; let key = config.attributes[ATTRIBUTE_KEY]; if (key != null) { needInitConfig[key] = config.attributes[ATTRIBUTE_DEFAULT_VALUE]; } let __attr_init__ = config.attributes[ATTRIBUTE_INIT]; if (typeof __attr_init__ === "function") { let __attr_result__ = __attr_init__(); if (typeof __attr_result__ === "boolean" && !__attr_result__) { return; } } let initMoreValue = config.attributes[ATTRIBUTE_INIT_MORE_VALUE]; if (initMoreValue && typeof initMoreValue === "object") { Object.assign(needInitConfig, initMoreValue); } let needInitConfigList = Object.keys(needInitConfig); if (!needInitConfigList.length) { if (config.type !== "button") { log.warn("请先配置键", config); } return; } needInitConfigList.forEach((__key) => { let __defaultValue = needInitConfig[__key]; if (that.$data.data.has(__key)) { log.warn("请检查该key(已存在): " + __key); } that.$data.data.set(__key, __defaultValue); }); } function loopInitDefaultValue(configList) { for (let index = 0; index < configList.length; index++) { let configItem = configList[index]; initDefaultValue(configItem); let childForms = configItem.forms; if (childForms && Array.isArray(childForms)) { loopInitDefaultValue(childForms); } } } for (let index = 0; index < contentConfigList.length; index++) { let leftContentConfigItem = contentConfigList[index]; if (!leftContentConfigItem.forms) { continue; } let rightContentConfigList = leftContentConfigItem.forms; if (rightContentConfigList && Array.isArray(rightContentConfigList)) { loopInitDefaultValue(rightContentConfigList); } } }, /** * 设置值 * @param key 键 * @param value 值 */ setValue(key, value) { let locaData = _GM_getValue(KEY, {}); let oldValue = locaData[key]; locaData[key] = value; _GM_setValue(KEY, locaData); if (this.$listener.listenData.has(key)) { this.$listener.listenData.get(key).callback(key, oldValue, value); } }, /** * 获取值 * @param key 键 * @param defaultValue 默认值 */ getValue(key, defaultValue) { let locaData = _GM_getValue(KEY, {}); let localValue = locaData[key]; if (localValue == null) { if (this.$data.data.has(key)) { return this.$data.data.get(key); } return defaultValue; } return localValue; }, /** * 删除值 * @param key 键 */ deleteValue(key) { let locaData = _GM_getValue(KEY, {}); let oldValue = locaData[key]; Reflect.deleteProperty(locaData, key); _GM_setValue(KEY, locaData); if (this.$listener.listenData.has(key)) { this.$listener.listenData.get(key).callback(key, oldValue, void 0); } }, /** * 监听调用setValue、deleteValue * @param key 需要监听的键 * @param callback */ addValueChangeListener(key, callback, option) { let listenerId = Math.random(); this.$listener.listenData.set(key, { id: listenerId, key, callback }); if (option) { if (option.immediate) { callback(key, this.getValue(key), this.getValue(key)); } } return listenerId; }, /** * 移除监听 * @param listenerId 监听的id */ removeValueChangeListener(listenerId) { let deleteKey = null; for (const [key, value] of this.$listener.listenData.entries()) { if (value.id === listenerId) { deleteKey = key; break; } } if (typeof deleteKey === "string") { this.$listener.listenData.delete(deleteKey); } else { console.warn("没有找到对应的监听器"); } }, /** * 主动触发菜单值改变的回调 * @param key 菜单键 * @param newValue 想要触发的新值,默认使用当前值 * @param oldValue 想要触发的旧值,默认使用当前值 */ triggerMenuValueChange(key, newValue, oldValue) { if (this.$listener.listenData.has(key)) { let listenData = this.$listener.listenData.get(key); if (typeof listenData.callback === "function") { let value = this.getValue(key); let __newValue = value; let __oldValue = value; if (typeof newValue !== "undefined" && arguments.length > 1) { __newValue = newValue; } if (typeof oldValue !== "undefined" && arguments.length > 2) { __oldValue = oldValue; } listenData.callback(key, __oldValue, __newValue); } } }, /** * 判断该键是否存在 * @param key 键 */ hasKey(key) { let locaData = _GM_getValue(KEY, {}); return key in locaData; }, /** * 自动判断菜单是否启用,然后执行回调 * @param key * @param callback 回调 * @param isReverse 逆反判断菜单启用 * @param checkEnableCallBack 自定义检测菜单的值,可自行决定是否强制启用菜单,true是启用菜单,false是不启用菜单 */ execMenu(key, callback, isReverse = false, checkEnableCallBack) { if (!(typeof key === "string" || typeof key === "object" && Array.isArray(key))) { throw new TypeError("key 必须是字符串或者字符串数组"); } let runKeyList = []; if (typeof key === "object" && Array.isArray(key)) { runKeyList = [...key]; } else { runKeyList.push(key); } let value = void 0; for (let index = 0; index < runKeyList.length; index++) { const runKey = runKeyList[index]; if (!this.$data.data.has(runKey)) { log.warn(`${key} 键不存在`); return; } let runValue = PopsPanel.getValue(runKey); if (isReverse) { runValue = !runValue; } if (typeof checkEnableCallBack === "function") { let checkResult = checkEnableCallBack(runKey, runValue); if (typeof checkResult === "boolean") { runValue = checkResult; } } if (!runValue) { break; } value = runValue; } if (value) { callback(value); } }, /** * 自动判断菜单是否启用,然后执行回调,只会执行一次 * @param key * @param callback 回调 * @param getValueFn 自定义处理获取当前值,值true是启用并执行回调,值false是不执行回调 * @param handleValueChangeFn 自定义处理值改变时的回调,值true是启用并执行回调,值false是不执行回调 * @param checkEnableCallBack 自定义检测菜单的值,可自行决定是否强制启用菜单,true是启用菜单,false是不启用菜单 */ execMenuOnce(key, callback, getValueFn, handleValueChangeFn, checkEnableCallBack) { if (typeof key !== "string") { throw new TypeError("key 必须是字符串"); } if (!this.$data.data.has(key)) { log.warn(`${key} 键不存在`); return; } if (this.$data.oneSuccessExecMenu.has(key)) { return; } this.$data.oneSuccessExecMenu.set(key, 1); let __getValue = () => { let localValue = PopsPanel.getValue(key); return typeof getValueFn === "function" ? getValueFn(key, localValue) : localValue; }; let resultStyleList = []; let dynamicPushStyleNode = ($style) => { let __value = __getValue(); let dynamicResultList = []; if ($style instanceof HTMLStyleElement) { dynamicResultList = [$style]; } else if (Array.isArray($style)) { dynamicResultList = [ ...$style.filter( (item) => item != null && item instanceof HTMLStyleElement ) ]; } if (__value) { resultStyleList = resultStyleList.concat(dynamicResultList); } else { for (let index = 0; index < dynamicResultList.length; index++) { let $css = dynamicResultList[index]; $css.remove(); dynamicResultList.splice(index, 1); index--; } } }; let checkMenuEnableCallBack = (currentValue) => { return typeof checkEnableCallBack === "function" ? checkEnableCallBack(key, currentValue) : currentValue; }; let changeCallBack = (currentValue) => { let resultList = []; if (checkMenuEnableCallBack(currentValue)) { let result = callback(currentValue, dynamicPushStyleNode); if (result instanceof HTMLStyleElement) { resultList = [result]; } else if (Array.isArray(result)) { resultList = [ ...result.filter( (item) => item != null && item instanceof HTMLStyleElement ) ]; } } for (let index = 0; index < resultStyleList.length; index++) { let $css = resultStyleList[index]; $css.remove(); resultStyleList.splice(index, 1); index--; } resultStyleList = [...resultList]; }; this.addValueChangeListener( key, (__key, oldValue, newValue) => { let __newValue = newValue; if (typeof handleValueChangeFn === "function") { __newValue = handleValueChangeFn(__key, newValue, oldValue); } changeCallBack(__newValue); } ); let value = __getValue(); if (value) { changeCallBack(value); } }, /** * 父子菜单联动,自动判断菜单是否启用,然后执行回调,只会执行一次 * @param key 菜单键 * @param childKey 子菜单键 * @param callback 回调 * @param replaceValueFn 用于修改mainValue,返回undefined则不做处理 */ execInheritMenuOnce(key, childKey, callback, replaceValueFn) { let that = this; const handleInheritValue = (key2, childKey2) => { let mainValue = that.getValue(key2); let childValue = that.getValue(childKey2); if (typeof replaceValueFn === "function") { let changedMainValue = replaceValueFn(mainValue, childValue); if (changedMainValue != null) { return changedMainValue; } } return mainValue; }; this.execMenuOnce( key, callback, () => { return handleInheritValue(key, childKey); }, () => { return handleInheritValue(key, childKey); } ); this.execMenuOnce( childKey, () => { }, () => false, () => { this.triggerMenuValueChange(key); return false; } ); }, /** * 根据自定义key只执行一次 * @param key 自定义key */ onceExec(key, callback) { if (typeof key !== "string") { throw new TypeError("key 必须是字符串"); } if (this.$data.onceExec.has(key)) { return; } callback(); this.$data.onceExec.set(key, 1); }, /** * 显示设置面板 */ showPanel() { __pops.panel({ title: { text: `${SCRIPT_NAME}-设置`, position: "center", html: false, style: "" }, content: this.getPanelContentConfig(), mask: { enable: true, clickEvent: { toClose: true, toHide: false } }, zIndex() { let maxZIndex = Utils.getMaxZIndex(); let popsMaxZIndex = __pops.config.InstanceUtils.getPopsMaxZIndex().zIndex; return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100; }, width: PanelUISize.setting.width, height: PanelUISize.setting.height, drag: true, only: true }); }, /** * 获取配置内容 */ getPanelContentConfig() { let configList = [ Component_Common, Component_Rule ]; return configList; } }; const CookieManager = { get cookieManagerApiName() { let managerApi = PopsPanel.getValue( "cookie-manager-api", "document.cookie" ); return managerApi; }, get cookieManager() { if (this.cookieManagerApiName === "GM_cookie") { return _GM_cookie; } else if (this.cookieManagerApiName === "cookieStore") { let cookieStore = _unsafeWindow.cookieStore; return { list(options, callback) { cookieStore.getAll().then((result) => { callback(result); }).catch((reason) => { log.error(reason); Qmsg.error(reason.toString()); }); }, set(cookieInfo, callback) { cookieStore.set(cookieInfo).then(() => { callback(); }).catch((reason) => { callback(reason); }); }, delete(cookieInfo, callback) { cookieStore.delete(cookieInfo).then((result) => { callback(); }).catch((reason) => { callback(reason); }); } }; } else { return utilsCookieManager; } }, /** * 查询所有Cookie */ queryAllCookie() { return new Promise( (resolve, reject) => { try { this.cookieManager.list({}, (cookieListResult) => { let __cookieListResult__ = cookieListResult || []; __cookieListResult__ = __cookieListResult__.sort( (a, b) => a.name.localeCompare(b.name) ); resolve(__cookieListResult__); }); } catch (error) { log.error(error); Qmsg.error(error.toString()); reject(error); } } ); }, /** * 清除所有Cookie */ deleteAllCookie() { return new Promise((resolve, reject) => { try { this.cookieManager.list({}, async (cookieListResult) => { const __cookieListResult__ = cookieListResult || []; const result = { success: 0, error: 0 }; for (let index = 0; index < __cookieListResult__.length; index++) { const cookieListItem = __cookieListResult__[index]; let deleteError = await new Promise((deleteResolve) => { this.deleteCookie(cookieListItem).then((deleteResult) => { deleteResolve(deleteResult); }); }); if (deleteError) { result.error++; } else { result.success++; } } resolve(result); }); } catch (error) { log.error(error); Qmsg.error(error.toString()); reject(error); } }); }, /** * 添加Cookie */ addCookie(cookieInfo) { return new Promise((resolve, reject) => { try { delete cookieInfo.hostOnly; CookieManager.cookieManager.set(cookieInfo, (error) => { log.info(["添加Cookie:" + cookieInfo.name, cookieInfo]); resolve(error); }); } catch (error) { log.error(error); Qmsg.error(error.toString()); reject(error); } }); }, /** * 删除Cookie */ deleteCookie(cookieInfo) { return new Promise((resolve, reject) => { try { CookieManager.cookieManager.delete(cookieInfo, (error) => { log.info(["删除Cookie:" + cookieInfo.name, cookieInfo]); resolve(error); }); } catch (error) { log.error(error); Qmsg.error(error.toString()); reject(error); } }); }, /** * 更新Cookie */ updateCookie(cookieInfo) { return new Promise( async (resolve, reject) => { let result; try { let deleteError = await CookieManager.deleteCookie(cookieInfo); if (deleteError) { throw new TypeError(deleteError.toString()); } let addError = await CookieManager.addCookie(cookieInfo); if (addError) { throw new TypeError(addError.toString()); } } catch (error) { result = error; } finally { log.info(["更新Cookie:" + cookieInfo.name, cookieInfo]); resolve(result); } } ); } }; let edit_ui_input = (text, getValue, setValue, disabled) => { let config = { text, type: "input", isNumber: false, isPassword: false, props: {}, attributes: {}, description: "", getValue() { return getValue(); }, callback(event, value) { setValue(value); }, placeholder: "", disabled: Boolean(disabled) }; return config; }; let edit_ui_select = (text, data, getValue, setValue, disabled) => { let config = { text, type: "select", description: "", attributes: {}, props: {}, getValue() { return getValue(); }, callback(event, isSelectedValue, isSelectedText) { let value = isSelectedValue; setValue(value); }, // @ts-ignore data, disabled: Boolean(disabled) }; return config; }; const CookieManagerEditView = { init() { }, /** * 显示视图 * @param cookieInfo 需要编辑的cookie * @param dialogCloseCallBack 弹窗关闭的回调 */ showView(__cookieInfo__, dialogCloseCallBack) { let isEdit = !!__cookieInfo__; let cookieInfo = utils.assign( { name: "", value: "", domain: window.location.hostname, path: "/", secure: false, hostOnly: false, httpOnly: false, sameSite: "lax", expirationDate: Date.now() + 60 * 60 * 24 * 30 * 1e3 }, __cookieInfo__, true ); if (CookieManager.cookieManagerApiName === "cookieStore") { if (cookieInfo.expires) { cookieInfo.expirationDate = cookieInfo.expires; } } let $dialog = __pops.confirm({ title: { text: isEdit ? "编辑Cookie" : "添加Cookie", position: "center" }, content: { text: "", html: true }, drag: true, btn: { position: "center", ok: { text: isEdit ? "编辑" : "添加", async callback(eventDetails, event) { let valid = CookieManagerEditView.validCookieInfo(cookieInfo); if (!valid) { return; } cookieInfo.value = encodeURIComponent(cookieInfo.value); if (CookieManager.cookieManagerApiName === "document.cookie") { cookieInfo.domain = ""; } else if (CookieManager.cookieManagerApiName === "GM_cookie") { cookieInfo.expirationDate = Math.floor( cookieInfo.expirationDate / 1e3 ); } if (isEdit) { let result = await CookieManager.updateCookie(cookieInfo); if (result) { Qmsg.error(result.toString()); } else { Qmsg.success("修改成功"); eventDetails.close(); } } else { let result = await CookieManager.addCookie(cookieInfo); if (result) { Qmsg.error(result.toString()); } else { Qmsg.success("添加成功"); eventDetails.close(); } } if (typeof dialogCloseCallBack === "function") { dialogCloseCallBack(cookieInfo); } } }, cancel: { text: "取消" } }, mask: { enable: true }, width: window.innerWidth > 350 ? "350px" : "80vw", height: PanelUISize.setting.height, style: ( /*css*/ ` ${__pops.config.cssText.panelCSS} .pops-panel-input input:disabled{ color: #b4b4b4; } .pops-confirm-content{ padding: 10px; } .pops-confirm-content li{ display: flex; flex-direction: column; } .pops-panel-item-left-text{ margin-bottom: 5px; } .pops-panel-input.pops-input-disabled{ border: 1px solid #dcdfe6; } #cookie-item-property-expires{ border: 1px solid rgb(184, 184, 184, var(--pops-bd-opacity)); border-radius: 4px; background-color: #ffffff; width: 100%; height: 32px; padding: 0px 8px; } #cookie-item-property-expires:hover{ box-shadow: 0 0 0 1px #c0c4cc inset; } #cookie-item-property-expires:focus, #cookie-item-property-expires:focus-within{ outline: 0; border: 1px solid #409eff; border-radius: 4px; box-shadow: none; } ` ) }); let $editContent = $dialog.$shadowRoot.querySelector( ".pops-confirm-content" ); let panelHandleContentUtils = __pops.config.panelHandleContentUtils(); let $name = panelHandleContentUtils.createSectionContainerItem_input( edit_ui_input( "name", () => cookieInfo.name, (value) => cookieInfo.name = value, isEdit ) ); let $value = panelHandleContentUtils.createSectionContainerItem_input( edit_ui_input( "value", () => cookieInfo.value, (value) => cookieInfo.value = value ) ); let $domain = panelHandleContentUtils.createSectionContainerItem_input( edit_ui_input( "domain", () => cookieInfo.domain, (value) => cookieInfo.domain = value ) ); let $path = panelHandleContentUtils.createSectionContainerItem_input( edit_ui_input( "path", () => cookieInfo.path, (value) => cookieInfo.path = value ) ); let $expires; if (cookieInfo.session) { $expires = panelHandleContentUtils.createSectionContainerItem_input( edit_ui_input( "expires", () => "会话", (value) => { }, true ) ); } else { $expires = panelHandleContentUtils.createSectionContainerItem_own({ type: "own", getLiElementCallBack: function(liElement) { let $li = domUtils.createElement("li", { innerHTML: ( /*html*/ `

expires

` ) }); let $dateTime = $li.querySelector( "#cookie-item-property-expires" ); $dateTime.valueAsNumber = cookieInfo.expirationDate; domUtils.on( $dateTime, ["change", "input", "propertychange"], (event) => { utils.preventEvent(event); cookieInfo.expirationDate = $dateTime.valueAsNumber; } ); return $li; } }); } let $httpOnly = panelHandleContentUtils.createSectionContainerItem_select( edit_ui_select( "httpOnly", [ { text: "true", value: true }, { text: "false", value: false } ], () => cookieInfo.httpOnly, (value) => cookieInfo.httpOnly = value ) ); let $secure = panelHandleContentUtils.createSectionContainerItem_select( edit_ui_select( "secure", [ { text: "true", value: true }, { text: "false", value: false } ], () => cookieInfo.secure, (value) => cookieInfo.secure = value ) ); let sameSiteData = [ { text: "no_restriction", value: "no_restriction" }, { text: "lax", value: "lax" }, { text: "strict", value: "strict" }, { text: "unspecified", value: "unspecified" } ]; if (CookieManager.cookieManagerApiName === "cookieStore") { sameSiteData = [ { text: "lax", value: "lax" }, { text: "strict", value: "strict" }, { text: "none", value: "none" } ]; } let $sameSite = panelHandleContentUtils.createSectionContainerItem_select( edit_ui_select( "sameSite", sameSiteData, () => cookieInfo.sameSite, (value) => cookieInfo.sameSite = value ) ); domUtils.append($editContent, [$name, $value]); if (CookieManager.cookieManagerApiName === "GM_cookie") { domUtils.append($editContent, [ $domain, $path, $expires, $httpOnly, $secure, $sameSite ]); } else if (CookieManager.cookieManagerApiName === "cookieStore") { domUtils.append($editContent, [$domain, $path, $expires, $sameSite]); } }, /** * Cookie信息校验 */ validCookieInfo(cookieInfo) { if (cookieInfo.name == null || cookieInfo.name == "") { Qmsg.error("name不能为空"); return false; } if (cookieInfo.domain == null || cookieInfo.domain == "") { Qmsg.error("domain不能为空"); return false; } if (cookieInfo.path == null || cookieInfo.path == "") { Qmsg.error("path不能为空"); return false; } return true; } }; const CookieManagerView = { init() { this.registerMenu(); }, /** * 显示视图 */ async showView() { const $alert = __pops.alert({ title: { text: "Cookie编辑器", html: false, position: "center" }, content: { text: ( /*html*/ ` ` ), html: true }, btn: { ok: { enable: false } }, mask: { enable: true }, drag: true, width: PanelUISize.setting.width, height: PanelUISize.setting.height, style: ( /*css*/ ` ${__pops.config.cssText.panelCSS} .cookie-wrapper{ display: flex; flex-direction: column; padding: 10px; gap: 10px; } .cookie-control-wrapper{ display: flex; flex-wrap: wrap; padding: 0px 10px; gap: 5px; --button-margin-left: 0px; } .cookie-search-wrapper{ display: flex; align-items: center; } .cookie-search-inner{ width: 100%; padding: 0px 10px; } .cookie-search-inner input{ height: 30px; padding: 5px; width: 100%; } .cookie-search-inner input:focus-visible{ outline: none; } .cookie-setting, .cookie-search-setting{ display: flex; align-items: center; } .cookie-setting svg, .cookie-search-setting svg{ cursor: pointer; } .cookie-list-wrapper{ display: flex; flex-wrap: wrap; gap: 10px; } .cookie-item{ display: flex; flex-direction: column; padding: 10px 10px; margin: 0px 10px; background: #f1efef; border-radius: 10px; gap: 5px; box-sizing: border-box; width: 100%; } .cookie-item-group{ display: flex; align-items: center; } .cookie-item-group-left{ width: 100px; min-width: 100px; max-width: 100px; text-transform: capitalize } .cookie-item-group-control .cookie-item-group-right{ display: flex; align-items: center; gap: 10px; } .cookie-item-group-control .cookie-item-group-control-copy, .cookie-item-group-control .cookie-item-group-control-edit, .cookie-item-group-control .cookie-item-group-control-delete{ display: flex; align-items: center; } .cookie-item-group-control .cookie-item-group-control-delete svg{ width: 16px; height: 16px; } .cookie-item-group-control svg{ cursor: pointer; } ` ) }); const $search = $alert.$shadowRoot.querySelector( ".cookie-search-inner input" ); const $searchSetting = $alert.$shadowRoot.querySelector( ".cookie-search-setting" ); const $refresh = $alert.$shadowRoot.querySelector( ".cookie-control-refresh" ); const $add = $alert.$shadowRoot.querySelector( ".cookie-control-add" ); const $copyAll = $alert.$shadowRoot.querySelector( ".cookie-control-copy-all" ); const $clearAll = $alert.$shadowRoot.querySelector( ".cookie-control-clear-all" ); const $ruleManager = $alert.$shadowRoot.querySelector( ".cookie-control-rule-manager" ); const $setting = $alert.$shadowRoot.querySelector(".cookie-setting"); const $cookieListWrapper = $alert.$shadowRoot.querySelector( ".cookie-list-wrapper" ); let createCookieItemElement = (cookieInfo) => { const $cookieItem = domUtils.createElement("div", { className: "cookie-item", innerHTML: ( /*html*/ ` ` ) }); const cookieProperty = [ { leftText: "name", rightText: cookieInfo.name }, { leftText: "value", rightText: PopsPanel.getValue("decode-cookie-value") ? decodeURIComponent(cookieInfo.value) : encodeURIComponent(cookieInfo.value) } ]; if (CookieManager.cookieManagerApiName === "GM_cookie") { cookieInfo = cookieInfo; cookieProperty.push( { leftText: "domain", rightText: cookieInfo.domain }, { leftText: "path", rightText: cookieInfo.path }, { leftText: "session", rightText: JSON.stringify(cookieInfo.session) }, { leftText: "expires", rightText: cookieInfo.session ? "会话" : cookieInfo.expirationDate ? new Date(cookieInfo.expirationDate * 1e3).toISOString() : "未知" }, { leftText: "httpOnly", rightText: JSON.stringify(cookieInfo.httpOnly) }, { leftText: "hostOnly", rightText: JSON.stringify(cookieInfo.hostOnly) }, { leftText: "secure", rightText: JSON.stringify(cookieInfo.secure) }, { leftText: "sameSite", rightText: cookieInfo.sameSite } ); } else if (CookieManager.cookieManagerApiName === "cookieStore") { cookieInfo = cookieInfo; cookieProperty.push( { leftText: "domain", rightText: cookieInfo.domain }, { leftText: "path", rightText: cookieInfo.path }, { leftText: "expires", rightText: cookieInfo.expires ? new Date(cookieInfo.expires).toISOString() : "未知" }, { leftText: "secure", rightText: JSON.stringify(cookieInfo.secure) }, { leftText: "sameSite", rightText: cookieInfo.sameSite } ); } cookieProperty.forEach((it) => { const $cookieItemGroup = domUtils.createElement("div", { className: "cookie-item-group", innerHTML: ( /*html*/ ` ` ) }); domUtils.append($cookieItem, $cookieItemGroup); }); let $cookieItemGroupControl = domUtils.createElement("div", { className: "cookie-item-group cookie-item-group-control", innerHTML: ( /*html*/ ` ` ) }); let $cookieItemCopy = $cookieItemGroupControl.querySelector( ".cookie-item-group-control-copy" ); let $cookieItemEdit = $cookieItemGroupControl.querySelector( ".cookie-item-group-control-edit" ); let $cookieItemDelete = $cookieItemGroupControl.querySelector( ".cookie-item-group-control-delete" ); domUtils.on($cookieItemCopy, "click", (event) => { utils.preventEvent(event); let cookieText = cookieInfo.value; utils.setClip(cookieText).then((status) => { if (status) { Qmsg.success("复制成功"); } else { Qmsg.error("复制失败"); } }); }); domUtils.on($cookieItemEdit, "click", (event) => { utils.preventEvent(event); CookieManagerEditView.showView(cookieInfo, (__cookieInfo__) => { var _a2; let $newCookieItem = createCookieItemElement(__cookieInfo__); domUtils.after($cookieItem, $newCookieItem); (_a2 = $cookieItem.parentElement) == null ? void 0 : _a2.removeChild($cookieItem); }); }); domUtils.on($cookieItemDelete, "click", (event) => { utils.preventEvent(event); let result = confirm("确定删除该Cookie?"); if (!result) { return; } CookieManager.deleteCookie(cookieInfo).then((status) => { var _a2; if (!status) { Qmsg.success("删除成功"); (_a2 = $cookieItem.parentElement) == null ? void 0 : _a2.removeChild($cookieItem); } else { log.error(status); Qmsg.error("删除失败"); } }); }); domUtils.append($cookieItem, [$cookieItemGroupControl]); return $cookieItem; }; let updateCookieListGroup = async (filterCallBack) => { let cookieList = await CookieManager.queryAllCookie(); if (typeof filterCallBack === "function") { cookieList = cookieList.filter(filterCallBack); } domUtils.empty($cookieListWrapper); let $fragment = document.createDocumentFragment(); cookieList.forEach((cookieItem) => { if ( // @ts-ignore cookieItem.session && PopsPanel.getValue("exclude-session-cookie") ) { return; } const $cookieItem = createCookieItemElement(cookieItem); domUtils.append($fragment, $cookieItem); }); domUtils.append($cookieListWrapper, $fragment); }; updateCookieListGroup(); domUtils.on( $search, ["input", "propertychange"], utils.debounce((event) => { updateCookieListGroup((cookieItem) => { let searchText = domUtils.val($search); let enableRegExp = PopsPanel.getValue( "search-config-use-regexp" ); return enableRegExp ? Boolean(cookieItem.name.match(new RegExp(searchText))) : cookieItem.name.includes(searchText); }); }) ); domUtils.listenKeyboard( $search, "keypress", (keyName, keyValue, otherCodeList) => { if (keyName === "Enter" && otherCodeList.length === 0) { utils.dispatchEvent($search, "input"); } } ); domUtils.on($searchSetting, "click", (event) => { utils.preventEvent(event); let $settingAlert = __pops.alert({ title: { text: "搜索配置", position: "center" }, content: { text: "", html: true }, btn: { ok: { enable: false } }, drag: true, mask: { clickEvent: { toClose: true } }, width: PanelUISize.info.width, height: PanelUISize.info.height, style: ( /*css*/ ` ${__pops.config.cssText.panelCSS} .pops-alert-content li{ display: flex; justify-content: space-between; align-items: center; padding: 10px; } .pops-panel-item-left-desc-text{ line-height: normal; margin-top: 6px; font-size: 0.8em; color: rgb(108, 108, 108); } ` ) }); let $content = $settingAlert.$shadowRoot.querySelector( ".pops-alert-content" ); let panelHandleContentUtils = __pops.config.panelHandleContentUtils(); let $useRegExp = panelHandleContentUtils.createSectionContainerItem_switch( UISwitch( "启用正则表达式", "search-config-use-regexp", false, void 0, "使用正则表达式搜索Cookie名称" ) ); domUtils.append($content, $useRegExp); }); domUtils.on($refresh, "click", (event) => { utils.preventEvent(event); let searchText = domUtils.val($search); if (searchText == "") { updateCookieListGroup(); } else { utils.dispatchEvent($search, "input"); } }); domUtils.on($add, "click", (event) => { utils.preventEvent(event); CookieManagerEditView.showView(void 0, (__cookieInfo__) => { updateCookieListGroup(); }); }); domUtils.on($copyAll, "click", (event) => { utils.preventEvent(event); CookieManager.queryAllCookie().then((cookieList) => { cookieList = cookieList.filter((it) => { return !(it.session && PopsPanel.getValue("exclude-session-cookie")); }); if (cookieList.length === 0) { Qmsg.warning("没有Cookie可以复制"); return; } let cookieText = cookieList.map((it) => { let cookieItemValueText = it.value; return `${it.name}=${cookieItemValueText}; `; }).join(""); utils.setClip(cookieText).then((status) => { if (status) { Qmsg.success("复制成功"); } else { Qmsg.error("复制失败"); } }); }); }); domUtils.on($clearAll, "click", (event) => { utils.preventEvent(event); let result = window.confirm("确定清除全部Cookie?"); if (!result) { return; } CookieManager.deleteAllCookie().then((deleteInfo) => { if (deleteInfo.error) { Qmsg.warning( `清除成功:${deleteInfo.success} 失败:${deleteInfo.error}` ); } else { Qmsg.success("清除成功"); } updateCookieListGroup(); }); }); domUtils.on($ruleManager, "click", (event) => { utils.preventEvent(event); CookieRule.showView(); }); domUtils.on($setting, "click", (event) => { utils.preventEvent(event); let $settingAlert = __pops.alert({ title: { text: "设置", position: "center" }, content: { text: "", html: true }, btn: { ok: { enable: false } }, drag: true, mask: { clickEvent: { toClose: true } }, width: PanelUISize.info.width, height: PanelUISize.info.height, style: ( /*css*/ ` ${__pops.config.cssText.panelCSS} .pops-alert-content li{ display: flex; justify-content: space-between; align-items: center; padding: 10px; } .pops-panel-item-left-desc-text{ line-height: normal; margin-top: 6px; font-size: 0.8em; color: rgb(108, 108, 108); } ` ) }); let $content = $settingAlert.$shadowRoot.querySelector( ".pops-alert-content" ); let panelHandleContentUtils = __pops.config.panelHandleContentUtils(); let $useGM_cookie = panelHandleContentUtils.createSectionContainerItem_select( UISelect( "CookieManager Api", "cookie-manager-api", "document.cookie", [ { text: "document.cookie", value: "document.cookie" }, { text: "cookieStore", value: "cookieStore" }, { text: "GM_cookie", value: "GM_cookie" } ], () => { updateCookieListGroup(); }, "操作Cookie的Api函数" ) ); let $decodeValue = panelHandleContentUtils.createSectionContainerItem_switch( UISwitch( "解码Cookie值", "decode-cookie-value", false, () => { updateCookieListGroup(); }, "对Cookie值进行解码" ) ); let $excludeSessionCookie = panelHandleContentUtils.createSectionContainerItem_switch( UISwitch( "排除Session Cookie", "exclude-session-cookie", false, () => { updateCookieListGroup(); }, "过滤掉浏览器会话Cookie" ) ); domUtils.append($content, [ $useGM_cookie, $decodeValue, $excludeSessionCookie ]); }); }, /** * 注册脚本菜单 */ registerMenu() { const that = this; GM_Menu.add({ key: "cookie_manager_view", text: "⚙ Cookie管理", autoReload: false, isStoreValue: false, showText(text, enable) { return text; }, callback(data) { that.showView(); } }); } }; const CookieRuleController = { init() { this.execController(); domUtils.ready(() => { this.execController(); }); }, /** * 执行操作 */ execController() { for (let index = 0; index < CookieRule.$data.ruleData.length; index++) { const rule = CookieRule.$data.ruleData[index]; CookieManager.queryAllCookie().then(async (cookieListResult) => { for (let cookieInfoIndex = 0; cookieInfoIndex < cookieListResult.length; cookieInfoIndex++) { let cookieInfo = cookieListResult[cookieInfoIndex]; const cookieName = cookieInfo.name; const ruleCookieName = rule.data.cookieName; let flag = false; if (rule.data.enableRegExpToMatchCookieName) { let regExpCookieName = new RegExp(ruleCookieName, "i"); if (regExpCookieName.test(cookieName)) { flag = true; } } else { if (cookieName.includes(ruleCookieName)) { flag = true; } } if (flag) { let operationMode = rule.data.operationMode; if (operationMode === "delete") { CookieManager.deleteCookie(cookieInfo); } else if (operationMode === "extended" || operationMode === "extended-90" || operationMode === "extended-180" || operationMode === "extended-360") { let currentTime = Date.now(); let oneMonth = 30 * 24 * 60 * 60 * 1e3; let threeMonth = oneMonth * 3; let halfAYear = oneMonth * 6; let oneYear = oneMonth * 12; let checkTime = oneMonth; if (operationMode === "extended-90") { checkTime = threeMonth; } else if (operationMode === "extended-180") { checkTime = halfAYear; } else if (operationMode === "extended-360") { checkTime = oneYear; } let updateFlag = false; if (CookieManager.cookieManagerApiName === "document.cookie") { cookieInfo.expirationDate = currentTime + checkTime; updateFlag = true; } else if (CookieManager.cookieManagerApiName === "cookieStore") { let expireTime = cookieInfo.expires; if (typeof expireTime === "number" && expireTime - currentTime < checkTime) { cookieInfo.expires = expireTime + checkTime; updateFlag = true; } } else if (CookieManager.cookieManagerApiName === "GM_cookie") { let expireTime = cookieInfo.expirationDate; if (typeof expireTime === "number" && expireTime * 1e3 - currentTime < checkTime) { cookieInfo.expirationDate = expireTime + checkTime / 1e3; updateFlag = true; } } else { log.error( "未知的cookieManagerApiName", CookieManager.cookieManagerApiName ); } if (updateFlag) { await CookieManager.updateCookie(cookieInfo); } } } } }); } } }; PopsPanel.init(); CookieRule.init(); CookieRuleController.init(); CookieManagerView.init(); })(Qmsg, DOMUtils, Utils, pops);