您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
简单而强大的Cookie编辑器,允许您快速创建、编辑和删除Cookie
- // ==UserScript==
- // @name CookieManager
- // @namespace https://github.com/WhiteSevs/TamperMonkeyScript
- // @version 2025.7.12
- // @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.7.0/dist/index.umd.js
- // @require https://fastly.jsdelivr.net/npm/@whitesev/domutils@1.5.11/dist/index.umd.js
- // @require https://fastly.jsdelivr.net/npm/@whitesev/pops@2.1.13/dist/index.umd.js
- // @require https://fastly.jsdelivr.net/npm/qmsg@1.3.8/dist/index.umd.js
- // @connect *
- // @grant GM.cookie
- // @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 _GM = /* @__PURE__ */ (() => typeof GM != "undefined" ? GM : void 0)();
- 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 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 PanelUISize = {
- /**
- * 一般设置界面的尺寸
- */
- setting: {
- get width() {
- if (window.innerWidth < 550) {
- return "88vw";
- } else if (window.innerWidth < 700) {
- return "550px";
- } else {
- return "700px";
- }
- },
- get height() {
- if (window.innerHeight < 450) {
- return "70vh";
- } else if (window.innerHeight < 550) {
- return "450px";
- } else {
- return "550px";
- }
- }
- },
- /**
- * 信息界面,一般用于提示信息之类
- */
- info: {
- get width() {
- return window.innerWidth < 350 ? "350px" : "350px";
- },
- get height() {
- return window.innerHeight < 250 ? "250px" : "250px";
- }
- }
- };
- class StorageUtils {
- /** 存储的键名 */
- storageKey;
- listenerData;
- /**
- * 存储的键名,可以是多层的,如:a.b.c
- *
- * 那就是
- * {
- * "a": {
- * "b": {
- * "c": {
- * ...你的数据
- * }
- * }
- * }
- * }
- * @param key
- */
- constructor(key) {
- if (typeof key === "string") {
- let trimKey = key.trim();
- if (trimKey == "") {
- throw new Error("key参数不能为空字符串");
- }
- this.storageKey = trimKey;
- } else {
- throw new Error("key参数类型错误,必须是字符串");
- }
- this.listenerData = new Utils.Dictionary();
- }
- /**
- * 获取本地值
- */
- getLocalValue() {
- let localValue = _GM_getValue(this.storageKey);
- if (localValue == null) {
- localValue = {};
- this.setLocalValue(localValue);
- }
- return localValue;
- }
- /**
- * 设置本地值
- * @param value
- */
- setLocalValue(value) {
- _GM_setValue(this.storageKey, value);
- }
- /**
- * 设置值
- * @param key 键
- * @param value 值
- */
- set(key, value) {
- let oldValue = this.get(key);
- let localValue = this.getLocalValue();
- Reflect.set(localValue, key, value);
- this.setLocalValue(localValue);
- this.triggerValueChangeListener(key, oldValue, value);
- }
- /**
- * 获取值
- * @param key 键
- * @param defaultValue 默认值
- */
- get(key, defaultValue) {
- let localValue = this.getLocalValue();
- return Reflect.get(localValue, key) ?? defaultValue;
- }
- /**
- * 获取所有值
- */
- getAll() {
- let localValue = this.getLocalValue();
- return localValue;
- }
- /**
- * 删除值
- * @param key 键
- */
- delete(key) {
- let oldValue = this.get(key);
- let localValue = this.getLocalValue();
- Reflect.deleteProperty(localValue, key);
- this.setLocalValue(localValue);
- this.triggerValueChangeListener(key, oldValue, void 0);
- }
- /**
- * 判断是否存在该值
- */
- has(key) {
- let localValue = this.getLocalValue();
- return Reflect.has(localValue, key);
- }
- /**
- * 获取所有键
- */
- keys() {
- let localValue = this.getLocalValue();
- return Reflect.ownKeys(localValue);
- }
- /**
- * 获取所有值
- */
- values() {
- let localValue = this.getLocalValue();
- return Reflect.ownKeys(localValue).map(
- (key) => Reflect.get(localValue, key)
- );
- }
- /**
- * 清空所有值
- */
- clear() {
- _GM_deleteValue(this.storageKey);
- }
- /**
- * 监听值改变
- * + .set
- * + .delete
- * @param key 监听的键
- * @param callback 值改变的回调函数
- */
- addValueChangeListener(key, callback) {
- let listenerId = Math.random();
- let listenerData = this.listenerData.get(key) || [];
- listenerData.push({
- id: listenerId,
- key,
- callback
- });
- this.listenerData.set(key, listenerData);
- return listenerId;
- }
- /**
- * 移除监听
- * @param listenerId 监听的id或键名
- */
- removeValueChangeListener(listenerId) {
- let flag = false;
- for (const [key, listenerData] of this.listenerData.entries()) {
- for (let index = 0; index < listenerData.length; index++) {
- const value = listenerData[index];
- if (typeof listenerId === "string" && value.key === listenerId || typeof listenerId === "number" && value.id === listenerId) {
- listenerData.splice(index, 1);
- index--;
- flag = true;
- }
- }
- this.listenerData.set(key, listenerData);
- }
- return flag;
- }
- /**
- * 主动触发监听器
- * @param key 键
- * @param oldValue (可选)旧值
- * @param newValue (可选)新值
- */
- triggerValueChangeListener(key, oldValue, newValue) {
- if (!this.listenerData.has(key)) {
- return;
- }
- let listenerData = this.listenerData.get(key);
- for (let index = 0; index < listenerData.length; index++) {
- const data = listenerData[index];
- if (typeof data.callback === "function") {
- let value = this.get(key);
- let __newValue;
- let __oldValue;
- if (typeof oldValue !== "undefined" && arguments.length >= 2) {
- __oldValue = oldValue;
- } else {
- __oldValue = value;
- }
- if (typeof newValue !== "undefined" && arguments.length > 2) {
- __newValue = newValue;
- } else {
- __newValue = value;
- }
- data.callback(key, __oldValue, __newValue);
- }
- }
- }
- }
- const PopsPanelStorageApi = new StorageUtils(KEY);
- const PanelMenu = {
- $data: {
- __menuOption: [
- {
- key: "show_pops_panel_setting",
- text: "⚙ 设置",
- autoReload: false,
- isStoreValue: false,
- showText(text) {
- return text;
- },
- callback: () => {
- Panel.showPanel(PanelContent.getConfig(0));
- }
- }
- ],
- get menuOption() {
- return this.__menuOption;
- }
- },
- init() {
- this.initExtensionsMenu();
- },
- /**
- * 初始化菜单项
- */
- initExtensionsMenu() {
- if (!Panel.isTopWindow()) {
- return;
- }
- GM_Menu.add(this.$data.menuOption);
- },
- /**
- * 添加菜单项
- * @param option 菜单配置
- */
- addMenuOption(option) {
- if (!Array.isArray(option)) {
- option = [option];
- }
- this.$data.menuOption.push(...option);
- },
- /**
- * 更新菜单项
- * @param option 菜单配置
- */
- updateMenuOption(option) {
- if (!Array.isArray(option)) {
- option = [option];
- }
- option.forEach((optionItem) => {
- let findIndex = this.$data.menuOption.findIndex((it) => {
- return it.key === optionItem.key;
- });
- if (findIndex !== -1) {
- this.$data.menuOption[findIndex] = optionItem;
- }
- });
- },
- /**
- * 获取菜单项
- * @param [index=0] 索引
- */
- getMenuOption(index = 0) {
- return this.$data.menuOption[index];
- },
- /**
- * 删除菜单项
- * @param [index=0] 索引
- */
- deleteMenuOption(index = 0) {
- this.$data.menuOption.splice(index, 1);
- }
- };
- const Panel = {
- /** 数据 */
- $data: {
- /**
- * @private
- */
- __configDefaultValueData: null,
- /**
- * @private
- */
- __onceExecMenuData: null,
- /**
- * @private
- */
- __onceExecData: null,
- /**
- * @private
- */
- __panelConfig: {},
- $panel: null,
- /**
- * 菜单项的默认值
- */
- get configDefaultValueData() {
- if (this.__configDefaultValueData == null) {
- this.__configDefaultValueData = new utils.Dictionary();
- }
- return this.__configDefaultValueData;
- },
- /**
- * 成功只执行了一次的项
- */
- get onceExecMenuData() {
- if (this.__onceExecMenuData == null) {
- this.__onceExecMenuData = new utils.Dictionary();
- }
- return this.__onceExecMenuData;
- },
- /**
- * 成功只执行了一次的项
- */
- get onceExecData() {
- if (this.__onceExecData == null) {
- this.__onceExecData = new utils.Dictionary();
- }
- return this.__onceExecData;
- },
- /** 脚本名,一般用在设置的标题上 */
- get scriptName() {
- return SCRIPT_NAME;
- },
- /**
- * pops.panel的默认配置
- */
- get panelConfig() {
- return this.__panelConfig;
- },
- set panelConfig(value) {
- this.__panelConfig = value;
- },
- /** 菜单项的总值在本地数据配置的键名 */
- key: KEY,
- /** 菜单项在attributes上配置的菜单键 */
- attributeKeyName: ATTRIBUTE_KEY,
- /** 菜单项在attributes上配置的菜单默认值 */
- attributeDefaultValueName: ATTRIBUTE_DEFAULT_VALUE
- },
- init() {
- this.initContentDefaultValue();
- PanelMenu.init();
- },
- /** 判断是否是顶层窗口 */
- isTopWindow() {
- return _unsafeWindow.top === _unsafeWindow.self;
- },
- /** 初始化菜单项的默认值保存到本地数据中 */
- initContentDefaultValue() {
- const initDefaultValue = (config) => {
- if (!config.attributes) {
- return;
- }
- if (config.type === "button" || config.type === "forms" || config.type === "deepMenu") {
- 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) {
- log.warn(["请先配置键", config]);
- return;
- }
- needInitConfigList.forEach((__key) => {
- let __defaultValue = needInitConfig[__key];
- this.setDefaultValue(__key, __defaultValue);
- });
- };
- const 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);
- }
- }
- };
- const contentConfigList = [...PanelContent.getAllContentConfig()];
- for (let index = 0; index < contentConfigList.length; index++) {
- let leftContentConfigItem = contentConfigList[index];
- if (!leftContentConfigItem.forms) {
- continue;
- }
- const rightContentConfigList = leftContentConfigItem.forms;
- if (rightContentConfigList && Array.isArray(rightContentConfigList)) {
- loopInitDefaultValue(rightContentConfigList);
- }
- }
- },
- /**
- * 设置初始化使用的默认值
- */
- setDefaultValue(key, defaultValue) {
- if (this.$data.configDefaultValueData.has(key)) {
- log.warn("请检查该key(已存在): " + key);
- }
- this.$data.configDefaultValueData.set(key, defaultValue);
- },
- /**
- * 设置值
- * @param key 键
- * @param value 值
- */
- setValue(key, value) {
- PopsPanelStorageApi.set(key, value);
- },
- /**
- * 获取值
- * @param key 键
- * @param defaultValue 默认值
- */
- getValue(key, defaultValue) {
- let localValue = PopsPanelStorageApi.get(key);
- if (localValue == null) {
- if (this.$data.configDefaultValueData.has(key)) {
- return this.$data.configDefaultValueData.get(key);
- }
- return defaultValue;
- }
- return localValue;
- },
- /**
- * 删除值
- * @param key 键
- */
- deleteValue(key) {
- PopsPanelStorageApi.delete(key);
- },
- /**
- * 判断该键是否存在
- * @param key 键
- */
- hasKey(key) {
- return PopsPanelStorageApi.has(key);
- },
- /**
- * 监听调用setValue、deleteValue
- * @param key 需要监听的键
- * @param callback
- */
- addValueChangeListener(key, callback) {
- let listenerId = PopsPanelStorageApi.addValueChangeListener(
- key,
- (__key, __newValue, __oldValue) => {
- callback(key, __oldValue, __newValue);
- }
- );
- return listenerId;
- },
- /**
- * 移除监听
- * @param listenerId 监听的id
- */
- removeValueChangeListener(listenerId) {
- PopsPanelStorageApi.removeValueChangeListener(listenerId);
- },
- /**
- * 主动触发菜单值改变的回调
- * @param key 菜单键
- * @param newValue 想要触发的新值,默认使用当前值
- * @param oldValue 想要触发的旧值,默认使用当前值
- */
- triggerMenuValueChange(key, newValue, oldValue) {
- PopsPanelStorageApi.triggerValueChangeListener(key, oldValue, newValue);
- },
- /**
- * 移除已执行的仅执行一次的菜单
- * @param key 键
- */
- deleteExecMenuOnce(key) {
- this.$data.onceExecMenuData.delete(key);
- let flag = PopsPanelStorageApi.removeValueChangeListener(key);
- return flag;
- },
- /**
- * 移除已执行的仅执行一次的菜单
- * @param key 键
- */
- deleteOnceExec(key) {
- this.$data.onceExecData.delete(key);
- },
- /**
- * 执行菜单
- *
- * @param queryKey 键|键数组
- * @param callback 执行的回调函数
- * @param checkExec 判断是否执行回调
- *
- * (默认)如果想要每个菜单是`与`关系,即每个菜单都判断为开启,那么就判断它们的值&就行
- *
- * 如果想要任意菜单存在true再执行,那么判断它们的值|就行
- *
- * + 返回值都为`true`,执行回调,如果回调返回了<style>元素,该元素会在监听到值改变时被移除掉
- * + 返回值有一个为`false`,则不执行回调,且移除之前回调函数返回的<style>元素
- * @param once 是否只执行一次,默认true
- *
- * + true (默认)只执行一次,且会监听键的值改变
- * + false 不会监听键的值改变
- */
- exec(queryKey, callback, checkExec, once = true) {
- const that = this;
- let queryKeyFn;
- if (typeof queryKey === "string" || Array.isArray(queryKey)) {
- queryKeyFn = () => queryKey;
- } else {
- queryKeyFn = queryKey;
- }
- let isArrayKey = false;
- let queryKeyResult = queryKeyFn();
- let keyList = [];
- if (Array.isArray(queryKeyResult)) {
- isArrayKey = true;
- keyList = queryKeyResult;
- } else {
- keyList.push(queryKeyResult);
- }
- let findNotInDataKey = keyList.find(
- (it) => !this.$data.configDefaultValueData.has(it)
- );
- if (findNotInDataKey) {
- log.warn(`${findNotInDataKey} 键不存在`);
- return;
- }
- let storageKey = JSON.stringify(keyList);
- if (once) {
- if (this.$data.onceExecMenuData.has(storageKey)) {
- return;
- }
- this.$data.onceExecMenuData.set(storageKey, 1);
- }
- let storeValueList = [];
- let listenerIdList = [];
- let dynamicAddStyleNodeCallback = (value, $style) => {
- let dynamicResultList = [];
- if (!Array.isArray($style)) {
- $style = [$style];
- }
- $style.forEach(($styleItem) => {
- if ($styleItem == null) {
- return;
- }
- if ($styleItem instanceof HTMLStyleElement) {
- dynamicResultList.push($styleItem);
- return;
- }
- });
- {
- storeValueList = storeValueList.concat(dynamicResultList);
- }
- };
- let getMenuValue = (key) => {
- let value = this.getValue(key);
- return value;
- };
- let clearBeforeStoreValue = () => {
- for (let index = 0; index < storeValueList.length; index++) {
- let $css = storeValueList[index];
- $css.remove();
- storeValueList.splice(index, 1);
- index--;
- }
- };
- let checkMenuExec = () => {
- let flag = false;
- if (typeof checkExec === "function") {
- flag = checkExec(keyList);
- } else {
- flag = keyList.every((key) => getMenuValue(key));
- }
- return flag;
- };
- let valueChangeCallback = (valueOption) => {
- let execFlag = checkMenuExec();
- let resultList = [];
- if (execFlag) {
- let valueList = keyList.map((key) => this.getValue(key));
- let callbackResult = callback({
- value: isArrayKey ? valueList : valueList[0],
- addStyleElement: (...args) => {
- return dynamicAddStyleNodeCallback(true, ...args);
- }
- });
- if (!Array.isArray(callbackResult)) {
- callbackResult = [callbackResult];
- }
- callbackResult.forEach((it) => {
- if (it == null) {
- return;
- }
- if (it instanceof HTMLStyleElement) {
- resultList.push(it);
- return;
- }
- });
- }
- clearBeforeStoreValue();
- storeValueList = [...resultList];
- };
- once && keyList.forEach((key) => {
- let listenerId = this.addValueChangeListener(
- key,
- (key2, newValue, oldValue) => {
- valueChangeCallback();
- }
- );
- listenerIdList.push(listenerId);
- });
- valueChangeCallback();
- let result = {
- /**
- * 清空菜单执行情况
- *
- * + 清空存储的元素列表
- * + 清空值改变的监听器
- * + 清空存储的一次执行的键
- */
- clear() {
- this.clearStoreStyleElements();
- this.removeValueChangeListener();
- once && that.$data.onceExecMenuData.delete(storageKey);
- },
- /**
- * 清空存储的元素列表
- */
- clearStoreStyleElements: () => {
- return clearBeforeStoreValue();
- },
- /**
- * 移除值改变的监听器
- */
- removeValueChangeListener: () => {
- listenerIdList.forEach((listenerId) => {
- this.removeValueChangeListener(listenerId);
- });
- }
- };
- return result;
- },
- /**
- * 自动判断菜单是否启用,然后执行回调
- * @param key
- * @param callback 回调
- * @param [isReverse=false] 逆反判断菜单启用
- */
- execMenu(key, callback, isReverse = false) {
- return this.exec(
- key,
- (option) => {
- return callback(option);
- },
- (keyList) => {
- let execFlag = keyList.every((__key__) => {
- let flag = !!this.getValue(__key__);
- isReverse && (flag = !flag);
- return flag;
- });
- return execFlag;
- },
- false
- );
- },
- /**
- * 自动判断菜单是否启用,然后执行回调,只会执行一次
- *
- * 它会自动监听值改变(设置中的修改),改变后如果未执行,则执行一次
- * @param key
- * @param callback 回调
- * @param getValueFn 自定义处理获取当前值,值true是启用并执行回调,值false是不执行回调
- * @param handleValueChangeFn 自定义处理值改变时的回调,值true是启用并执行回调,值false是不执行回调
- */
- execMenuOnce(key, callback) {
- return this.exec(
- key,
- callback,
- (keyList) => {
- let execFlag = keyList.every((__key__) => {
- let flag = !!this.getValue(__key__);
- return flag;
- });
- return execFlag;
- },
- true
- );
- },
- /**
- * 根据key执行一次
- * @param key 键
- * @param callback 回调
- */
- onceExec(key, callback) {
- if (typeof key !== "string") {
- throw new TypeError("key 必须是字符串");
- }
- if (this.$data.onceExecData.has(key)) {
- return;
- }
- callback();
- this.$data.onceExecData.set(key, 1);
- },
- /**
- * 显示设置面板
- * @param content 显示的内容配置
- * @param [title] 标题
- * @param [preventDefaultContentConfig=false] 是否阻止默认添加内容配置(版本号)
- */
- showPanel(content, title = `${SCRIPT_NAME}-设置`, preventDefaultContentConfig = false) {
- let notHasBottomVersionContentConfig = content.some((it) => {
- let isBottom = typeof it.isBottom === "function" ? it.isBottom() : Boolean(it.isBottom);
- return !isBottom && it.id !== "script-version";
- });
- if (!preventDefaultContentConfig && notHasBottomVersionContentConfig) {
- content.push(...PanelContent.getDefaultBottomContentConfig());
- }
- let $panel = __pops.panel({
- ...{
- title: {
- text: title,
- position: "center",
- html: false,
- style: ""
- },
- content,
- btn: {
- close: {
- enable: true,
- callback: (details, event) => {
- details.close();
- this.$data.$panel = null;
- }
- }
- },
- mask: {
- enable: true,
- clickEvent: {
- toClose: true,
- toHide: false
- },
- clickCallBack: (originalRun, config) => {
- originalRun();
- this.$data.$panel = null;
- }
- },
- width: PanelUISize.setting.width,
- height: PanelUISize.setting.height,
- drag: true,
- only: true
- },
- ...this.$data.panelConfig
- });
- this.$data.$panel = $panel;
- }
- };
- 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 utils = Utils.noConflict();
- const domUtils = DOMUtils.noConflict();
- const __pops = pops;
- const log = new utils.Log(
- _GM_info,
- _unsafeWindow.console || _monkeyWindow.console
- );
- let SCRIPT_NAME = _GM_info?.script?.name || void 0;
- pops.config.Utils.AnyTouch();
- 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 Panel.getValue(
- PanelSettingConfig.qmsg_config_position.key,
- PanelSettingConfig.qmsg_config_position.defaultValue
- );
- }
- },
- maxNums: {
- get() {
- return Panel.getValue(
- PanelSettingConfig.qmsg_config_maxnums.key,
- PanelSettingConfig.qmsg_config_maxnums.defaultValue
- );
- }
- },
- showReverse: {
- get() {
- return Panel.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) => {
- if ($ele?.classList?.contains("qmsg-shadow-container")) {
- return false;
- }
- if ($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({
- xmlHttpRequest: _GM_xmlhttpRequest,
- logDetails: DEBUG
- });
- httpx.interceptors.request.use((data) => {
- return data;
- });
- httpx.interceptors.response.use(void 0, (data) => {
- log.error("拦截器-请求错误", data);
- if (data.type === "onabort") {
- Qmsg.warning("请求取消", { consoleLogContent: true });
- } else if (data.type === "onerror") {
- Qmsg.error("请求异常", { consoleLogContent: true });
- } else if (data.type === "ontimeout") {
- Qmsg.error("请求超时", { consoleLogContent: true });
- } else {
- Qmsg.error("其它错误", { consoleLogContent: true });
- }
- return data;
- });
- ({
- 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 cookieManager = new utils.GM_Cookie();
- const PanelContent = {
- $data: {
- /**
- * @private
- */
- __contentConfig: null,
- get contentConfig() {
- if (this.__contentConfig == null) {
- this.__contentConfig = new utils.Dictionary();
- }
- return this.__contentConfig;
- }
- },
- /**
- * 设置所有配置项,用于初始化默认的值
- *
- * 如果是第一组添加的话,那么它默认就是设置菜单打开的配置
- * @param configList 配置项
- */
- addContentConfig(configList) {
- if (!Array.isArray(configList)) {
- configList = [configList];
- }
- let index = this.$data.contentConfig.keys().length;
- this.$data.contentConfig.set(index, configList);
- },
- /**
- * 获取所有的配置内容,用于初始化默认的值
- */
- getAllContentConfig() {
- return this.$data.contentConfig.values().flat();
- },
- /**
- * 获取配置内容
- * @param index 配置索引
- */
- getConfig(index = 0) {
- return this.$data.contentConfig.get(index) ?? [];
- },
- /**
- * 获取默认左侧底部的配置项
- */
- getDefaultBottomContentConfig() {
- return [
- {
- id: "script-version",
- title: `版本:${_GM_info?.script?.version || "未知"}`,
- isBottom: true,
- forms: [],
- clickFirstCallback(event, rightHeaderElement, rightContainerElement) {
- let supportURL = _GM_info?.script?.supportURL || _GM_info?.script?.namespace;
- if (typeof supportURL === "string" && utils.isNotNull(supportURL)) {
- window.open(supportURL, "_blank");
- }
- return false;
- }
- }
- ];
- }
- };
- let applyObjectThis = (obj) => {
- if (typeof obj === "object" && obj != null || typeof obj === "function") {
- Object.keys(obj).forEach((key) => {
- if (typeof obj[key] === "function") {
- obj[key] = obj[key].bind(obj);
- }
- });
- }
- };
- const __GM_cookie__ = _GM_cookie;
- applyObjectThis(__GM_cookie__);
- applyObjectThis(cookieManager);
- const CookieManager = {
- get cookieManagerApiName() {
- let managerApi = Panel.getValue(
- "cookie-manager-api",
- "document.cookie"
- );
- return managerApi;
- },
- get cookieManager() {
- if (this.cookieManagerApiName === "GM_cookie") {
- return {
- list(options, callback) {
- __GM_cookie__.list(options, (result) => {
- callback(result);
- });
- },
- set(cookieInfo, callback) {
- __GM_cookie__.set(
- cookieInfo,
- (result) => {
- callback(result);
- }
- );
- },
- delete(cookieInfo, callback) {
- __GM_cookie__.delete(cookieInfo, (result) => {
- callback(result);
- });
- }
- };
- } else if (this.cookieManagerApiName === "GM.cookie") {
- return {
- list(options, callback) {
- _GM.cookie.list().then((result) => {
- callback(result);
- });
- },
- set(cookieInfo, callback) {
- _GM.cookie.set(
- cookieInfo
- ).then((result) => {
- callback(result ?? null);
- }).catch((reason) => {
- callback(reason);
- });
- },
- delete(cookieInfo, callback) {
- _GM.cookie.delete(cookieInfo).then((result) => {
- callback(result ?? null);
- }).catch((reason) => {
- callback(reason);
- });
- }
- };
- } 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 cookieManager;
- }
- },
- /**
- * 查询所有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 {
- Reflect.deleteProperty(cookieInfo, "hostOnly");
- CookieManager.cookieManager.set(
- cookieInfo,
- (error) => {
- if (false) ;
- 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) => {
- if (false) ;
- 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 {
- resolve(result);
- }
- }
- );
- }
- };
- const PanelComponents = {
- $data: {
- __storeApiFn: null,
- get storeApiValue() {
- if (!this.__storeApiFn) {
- this.__storeApiFn = new Utils.Dictionary();
- }
- return this.__storeApiFn;
- }
- },
- /**
- * 获取自定义的存储接口
- * @param type 组件类型
- */
- getStorageApi(type) {
- if (!this.hasStorageApi(type)) {
- return;
- }
- return this.$data.storeApiValue.get(type);
- },
- /**
- * 判断是否存在自定义的存储接口
- * @param type 组件类型
- */
- hasStorageApi(type) {
- return this.$data.storeApiValue.has(type);
- },
- /**
- * 设置自定义的存储接口
- * @param type 组件类型
- * @param storageApiValue 存储接口
- */
- setStorageApi(type, storageApiValue) {
- this.$data.storeApiValue.set(type, storageApiValue);
- },
- /**
- * 初始化组件的存储接口属性
- *
- * @param type 组件类型
- * @param config 组件配置,必须包含prop属性
- * @param storageApiValue 存储接口
- */
- initComponentsStorageApi(type, config, storageApiValue) {
- let propsStorageApi;
- if (this.hasStorageApi(type)) {
- propsStorageApi = this.getStorageApi(type);
- } else {
- propsStorageApi = storageApiValue;
- }
- this.setComponentsStorageApiProperty(config, propsStorageApi);
- },
- /**
- * 设置组件的存储接口属性
- * @param config 组件配置,必须包含prop属性
- * @param storageApiValue 存储接口
- */
- setComponentsStorageApiProperty(config, storageApiValue) {
- Reflect.set(config.props, PROPS_STORAGE_API, storageApiValue);
- }
- };
- const UISwitch = function(text, key, defaultValue, clickCallback, description, afterAddToUListCallBack) {
- let result = {
- text,
- type: "switch",
- description,
- attributes: {},
- props: {},
- getValue() {
- let storageApiValue = this.props[PROPS_STORAGE_API];
- return Boolean(storageApiValue.get(key, defaultValue));
- },
- callback(event, __value) {
- let value = Boolean(__value);
- log.success(`${value ? "开启" : "关闭"} ${text}`);
- if (typeof clickCallback === "function") {
- let result2 = clickCallback(event, value);
- if (result2) {
- return;
- }
- }
- let storageApiValue = this.props[PROPS_STORAGE_API];
- storageApiValue.set(key, value);
- },
- afterAddToUListCallBack
- };
- Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
- Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
- PanelComponents.initComponentsStorageApi(
- "switch",
- result,
- {
- get(key2, defaultValue2) {
- return Panel.getValue(key2, defaultValue2);
- },
- set(key2, value) {
- Panel.setValue(key2, value);
- }
- }
- );
- return result;
- };
- const CookieInfoTransform = {
- /**
- * 对编辑前的cookie信息进行值转换
- */
- beforeEdit(cookieInfo) {
- const cookieManagerApiName = CookieManager.cookieManagerApiName;
- if (cookieManagerApiName === "cookieStore") {
- if (typeof cookieInfo.expires === "number") {
- cookieInfo.expirationDate = cookieInfo.expires;
- }
- } else if (cookieManagerApiName === "GM_cookie" || cookieManagerApiName === "GM.cookie") {
- if (typeof cookieInfo.expirationDate === "number") {
- cookieInfo.expirationDate = cookieInfo.expirationDate * 1e3;
- }
- }
- return cookieInfo;
- },
- /**
- * 对编辑后的cookie信息进行值转换
- */
- afterEdit(cookieInfo) {
- const cookieManagerApiName = CookieManager.cookieManagerApiName;
- if (cookieManagerApiName === "document.cookie") {
- cookieInfo.domain = "";
- } else if (cookieManagerApiName === "cookieStore") {
- if (typeof cookieInfo.expirationDate === "number") {
- cookieInfo.expires = cookieInfo.expirationDate;
- }
- } else if (cookieManagerApiName === "GM_cookie" || cookieManagerApiName === "GM.cookie") {
- if (typeof cookieInfo.expirationDate === "number") {
- cookieInfo.expirationDate = Math.floor(
- cookieInfo.expirationDate / 1e3
- );
- }
- }
- return cookieInfo;
- }
- };
- 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);
- },
- data: typeof data === "function" ? data() : 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
- );
- cookieInfo = CookieInfoTransform.beforeEdit(cookieInfo);
- 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);
- cookieInfo = CookieInfoTransform.afterEdit(cookieInfo);
- 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 panelHandlerComponents = __pops.config.PanelHandlerComponents();
- let $name = panelHandlerComponents.createSectionContainerItem_input(
- edit_ui_input(
- "name",
- () => cookieInfo.name,
- (value) => cookieInfo.name = value,
- isEdit
- )
- );
- let $value = panelHandlerComponents.createSectionContainerItem_input(
- edit_ui_input(
- "value",
- () => cookieInfo.value,
- (value) => cookieInfo.value = value
- )
- );
- let $domain = panelHandlerComponents.createSectionContainerItem_input(
- edit_ui_input(
- "domain",
- () => cookieInfo.domain,
- (value) => cookieInfo.domain = value
- )
- );
- let $path = panelHandlerComponents.createSectionContainerItem_input(
- edit_ui_input(
- "path",
- () => cookieInfo.path,
- (value) => cookieInfo.path = value
- )
- );
- let $expires;
- if (cookieInfo.session) {
- $expires = panelHandlerComponents.createSectionContainerItem_input(
- edit_ui_input(
- "expires",
- () => "会话",
- (value) => {
- },
- true
- )
- );
- } else {
- $expires = panelHandlerComponents.createSectionContainerItem_own({
- type: "own",
- getLiElementCallBack: function(liElement) {
- let $li = domUtils.createElement("li", {
- innerHTML: (
- /*html*/
- `
- <div class="pops-panel-item-left-text">
- <p class="pops-panel-item-left-main-text">expires</p>
- </div>
- <div class="pops-panel-item-right-wrapper">
- <input type="datetime-local" id="cookie-item-property-expires">
- </div>
- `
- )
- });
- 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 = panelHandlerComponents.createSectionContainerItem_select(
- edit_ui_select(
- "httpOnly",
- [
- {
- text: "true",
- value: true
- },
- {
- text: "false",
- value: false
- }
- ],
- () => cookieInfo.httpOnly,
- (value) => cookieInfo.httpOnly = value
- )
- );
- let $secure = panelHandlerComponents.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 = panelHandlerComponents.createSectionContainerItem_select(
- edit_ui_select(
- "sameSite",
- sameSiteData,
- () => cookieInfo.sameSite,
- (value) => cookieInfo.sameSite = value
- )
- );
- domUtils.append($editContent, [$name, $value]);
- if (CookieManager.cookieManagerApiName === "GM_cookie" || 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 UISelect = function(text, key, defaultValue, data, changeCallback, description) {
- let selectData = [];
- if (typeof data === "function") {
- selectData = data();
- } else {
- selectData = data;
- }
- let result = {
- text,
- type: "select",
- description,
- attributes: {},
- props: {},
- getValue() {
- let storageApiValue = this.props[PROPS_STORAGE_API];
- return storageApiValue.get(key, defaultValue);
- },
- callback(event, isSelectedValue, isSelectedText) {
- let value = isSelectedValue;
- log.info(`选择:${isSelectedText}`);
- if (typeof changeCallback === "function") {
- let result2 = changeCallback(event, value, isSelectedText);
- if (result2) {
- return;
- }
- }
- let storageApiValue = this.props[PROPS_STORAGE_API];
- storageApiValue.set(key, value);
- },
- data: selectData
- };
- Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
- Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
- PanelComponents.initComponentsStorageApi(
- "select",
- result,
- {
- get(key2, defaultValue2) {
- return Panel.getValue(key2, defaultValue2);
- },
- set(key2, value) {
- Panel.setValue(key2, value);
- }
- }
- );
- return result;
- };
- const UIInput = function(text, key, defaultValue, description, changeCallback, placeholder = "", isNumber, isPassword, afterAddToUListCallBack) {
- let result = {
- text,
- type: "input",
- isNumber: Boolean(isNumber),
- isPassword: Boolean(isPassword),
- attributes: {},
- props: {},
- description,
- afterAddToUListCallBack,
- getValue() {
- let storageApiValue = this.props[PROPS_STORAGE_API];
- return storageApiValue.get(key, defaultValue);
- },
- callback(event, value, valueAsNumber) {
- let storageApiValue = this.props[PROPS_STORAGE_API];
- storageApiValue.set(key, value);
- },
- placeholder
- };
- Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
- Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
- PanelComponents.initComponentsStorageApi(
- "input",
- result,
- {
- get(key2, defaultValue2) {
- return Panel.getValue(key2, defaultValue2);
- },
- set(key2, value) {
- Panel.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 storageApiValue = this.props[PROPS_STORAGE_API];
- let value = storageApiValue.get(key, defaultValue);
- if (Array.isArray(value)) {
- return value.join("\n");
- }
- return value;
- },
- callback(event, value) {
- let storageApiValue = this.props[PROPS_STORAGE_API];
- storageApiValue.set(key, value);
- }
- };
- Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
- Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
- PanelComponents.initComponentsStorageApi(
- "switch",
- result,
- {
- get(key2, defaultValue2) {
- return Panel.getValue(key2, defaultValue2);
- },
- set(key2, value) {
- Panel.setValue(key2, value);
- }
- }
- );
- return result;
- };
- class RuleEditView {
- option;
- constructor(option) {
- this.option = option;
- }
- /**
- * 显示视图
- */
- async showView() {
- let $dialog = __pops.confirm({
- title: {
- text: this.option.title,
- position: "center"
- },
- content: {
- text: (
- /*html*/
- `
- <form class="rule-form-container" onsubmit="return false">
- <ul class="rule-form-ulist"></ul>
- <input type="submit" style="display: none;" />
- </form>
- `
- ),
- html: true
- },
- btn: utils.assign(
- {
- ok: {
- callback: async () => {
- await submitSaveOption();
- }
- }
- },
- this.option.btn || {},
- true
- ),
- drag: true,
- mask: {
- enable: 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;
- }
- .rule-form-ulist-dynamic{
- --button-margin-top: 0px;
- --button-margin-right: 0px;
- --button-margin-bottom: 0px;
- --button-margin-left: 0px;
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- padding: 5px 0px 5px 20px;
- }
- .rule-form-ulist-dynamic__inner{
- width: 100%;
- }
- .rule-form-ulist-dynamic__inner-container{
- display: flex;
- align-items: center;
- }
- .dynamic-forms{
- width: 100%;
- }
- .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;
- }
- .pops-panel-item-left-desc-text{
- line-height: normal;
- margin-top: 6px;
- font-size: 0.8em;
- color: rgb(108, 108, 108);
- }
- ${this.option?.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 {
- option;
- constructor(option) {
- this.option = option;
- }
- showView() {
- let $alert = __pops.alert({
- title: {
- text: this.option.title,
- position: "center"
- },
- content: {
- text: (
- /*html*/
- `
- <div class="filter-container"></div>
- `
- )
- },
- btn: {
- ok: {
- text: "关闭",
- type: "default"
- }
- },
- drag: true,
- 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 {
- option;
- constructor(option) {
- this.option = option;
- }
- /**
- * 显示视图
- * @param filterCallBack 返回值为false隐藏,true则不隐藏(不处理)
- */
- async showView(filterCallBack) {
- let $popsConfirm = __pops.confirm({
- title: {
- text: this.option.title,
- position: "center"
- },
- content: {
- text: (
- /*html*/
- `
- <div class="rule-view-container">
- </div>
- `
- ),
- html: true
- },
- btn: {
- merge: true,
- reverse: false,
- position: "space-between",
- ok: {
- enable: this.option?.bottomControls?.add?.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: this.option?.bottomControls?.filter?.enable || false,
- type: "default",
- text: "过滤",
- callback: (details, event) => {
- if (typeof this.option?.bottomControls?.filter?.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: this.option.bottomControls?.filter?.title ?? "过滤规则",
- filterOption: this.option.bottomControls?.filter?.option || [],
- execFilterCallBack() {
- domUtils.text($button, "取消过滤");
- },
- getAllRuleInfo: () => {
- return getAllRuleElement().map(($el) => {
- return {
- data: this.parseRuleItemElement($el).data,
- $el
- };
- });
- }
- });
- ruleFilterView.showView();
- }
- }
- },
- other: {
- enable: this.option?.bottomControls?.clear?.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) => {
- log.success("清空所有");
- if (typeof this.option?.bottomControls?.clear?.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
- },
- 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) {
- log.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*/
- `
- <div class="rule-name">${name}</div>
- <div class="rule-controls">
- <div class="rule-controls-enable">
- <div class="pops-panel-switch">
- <input class="pops-panel-switch__input" type="checkbox">
- <span class="pops-panel-switch__core">
- <div class="pops-panel-switch__action">
- </div>
- </span>
- </div>
- </div>
- <div class="rule-controls-edit">
- ${__pops.config.iconSVG.edit}
- </div>
- <div class="rule-controls-delete">
- ${__pops.config.iconSVG.delete}
- </div>
- </div>
- `
- )
- });
- 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 panelHandlerComponents = __pops.config.PanelHandlerComponents();
- 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 = panelHandlerComponents.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 = panelHandlerComponents.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 = panelHandlerComponents.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 = panelHandlerComponents.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 = panelHandlerComponents.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 = panelHandlerComponents.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 = panelHandlerComponents.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 = panelHandlerComponents.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*/
- `
- <div class="import-mode" data-mode="local">本地导入</div>
- <div class="import-mode" data-mode="network">网络导入</div>
- `
- ),
- 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) => {
- if (!$input.files?.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 CookieManagerView = {
- init() {
- this.registerMenu();
- },
- /**
- * 显示视图
- */
- async showView() {
- const $alert = __pops.alert({
- title: {
- text: "Cookie编辑器",
- html: false,
- position: "center"
- },
- content: {
- text: (
- /*html*/
- `
- <div class="cookie-wrapper">
- <div class="cookie-search-wrapper">
- <div class="cookie-search-inner">
- <input type="text" placeholder="搜索Cookie名称">
- </div>
- <div class="cookie-search-setting">
- <svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4368" width="28" height="28">
- <path fill="#2c2c2c" d="M439.264 208a16 16 0 0 0-16 16v67.968a239.744 239.744 0 0 0-46.496 26.896l-58.912-34a16 16 0 0 0-21.856 5.856l-80 138.56a16 16 0 0 0 5.856 21.856l58.896 34a242.624 242.624 0 0 0 0 53.728l-58.88 34a16 16 0 0 0-6.72 20.176l0.848 1.68 80 138.56a16 16 0 0 0 21.856 5.856l58.912-34a239.744 239.744 0 0 0 46.496 26.88V800a16 16 0 0 0 16 16h160a16 16 0 0 0 16-16v-67.968a239.744 239.744 0 0 0 46.512-26.896l58.912 34a16 16 0 0 0 21.856-5.856l80-138.56a16 16 0 0 0-4.288-20.832l-1.568-1.024-58.896-34a242.624 242.624 0 0 0 0-53.728l58.88-34a16 16 0 0 0 6.72-20.176l-0.848-1.68-80-138.56a16 16 0 0 0-21.856-5.856l-58.912 34a239.744 239.744 0 0 0-46.496-26.88V224a16 16 0 0 0-16-16h-160z m32 48h96v67.376l28.8 12.576c13.152 5.76 25.632 12.976 37.184 21.52l25.28 18.688 58.448-33.728 48 83.136-58.368 33.68 3.472 31.2a194.624 194.624 0 0 1 0 43.104l-3.472 31.2 58.368 33.68-48 83.136-58.432-33.728-25.296 18.688c-11.552 8.544-24.032 15.76-37.184 21.52l-28.8 12.576V768h-96v-67.376l-28.784-12.576c-13.152-5.76-25.632-12.976-37.184-21.52l-25.28-18.688-58.448 33.728-48-83.136 58.368-33.68-3.472-31.2a194.624 194.624 0 0 1 0-43.104l3.472-31.2-58.368-33.68 48-83.136 58.432 33.728 25.296-18.688a191.744 191.744 0 0 1 37.184-21.52l28.8-12.576V256z m47.28 144a112 112 0 1 0 0 224 112 112 0 0 0 0-224z m0 48a64 64 0 1 1 0 128 64 64 0 0 1 0-128z"></path>
- </svg>
- </div>
- </div>
- <div class="cookie-control-wrapper">
- <button class="cookie-control-refresh" type="default">刷新</button>
- <button class="cookie-control-add" type="default">添加</button>
- <button class="cookie-control-copy-all" type="default">复制全部</button>
- <button class="cookie-control-clear-all" type="default">清除全部</button>
- <button class="cookie-control-rule-manager" type="default">规则管理</button>
- <div class="cookie-setting">
- <svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4368" width="28" height="28">
- <path fill="#2c2c2c" d="M439.264 208a16 16 0 0 0-16 16v67.968a239.744 239.744 0 0 0-46.496 26.896l-58.912-34a16 16 0 0 0-21.856 5.856l-80 138.56a16 16 0 0 0 5.856 21.856l58.896 34a242.624 242.624 0 0 0 0 53.728l-58.88 34a16 16 0 0 0-6.72 20.176l0.848 1.68 80 138.56a16 16 0 0 0 21.856 5.856l58.912-34a239.744 239.744 0 0 0 46.496 26.88V800a16 16 0 0 0 16 16h160a16 16 0 0 0 16-16v-67.968a239.744 239.744 0 0 0 46.512-26.896l58.912 34a16 16 0 0 0 21.856-5.856l80-138.56a16 16 0 0 0-4.288-20.832l-1.568-1.024-58.896-34a242.624 242.624 0 0 0 0-53.728l58.88-34a16 16 0 0 0 6.72-20.176l-0.848-1.68-80-138.56a16 16 0 0 0-21.856-5.856l-58.912 34a239.744 239.744 0 0 0-46.496-26.88V224a16 16 0 0 0-16-16h-160z m32 48h96v67.376l28.8 12.576c13.152 5.76 25.632 12.976 37.184 21.52l25.28 18.688 58.448-33.728 48 83.136-58.368 33.68 3.472 31.2a194.624 194.624 0 0 1 0 43.104l-3.472 31.2 58.368 33.68-48 83.136-58.432-33.728-25.296 18.688c-11.552 8.544-24.032 15.76-37.184 21.52l-28.8 12.576V768h-96v-67.376l-28.784-12.576c-13.152-5.76-25.632-12.976-37.184-21.52l-25.28-18.688-58.448 33.728-48-83.136 58.368-33.68-3.472-31.2a194.624 194.624 0 0 1 0-43.104l3.472-31.2-58.368-33.68 48-83.136 58.432 33.728 25.296-18.688a191.744 191.744 0 0 1 37.184-21.52l28.8-12.576V256z m47.28 144a112 112 0 1 0 0 224 112 112 0 0 0 0-224z m0 48a64 64 0 1 1 0 128 64 64 0 0 1 0-128z"></path>
- </svg>
- </div>
- </div>
- <div class="cookie-list-wrapper">
- </div>
- </div>
- `
- ),
- 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 8px;
- width: 100%;
- border-radius: 6px;
- }
- .cookie-search-inner input::placeholder{
- display: flex;
- align-items: baseline;
- }
- .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*/
- `
- `
- ),
- "data-cookie-info": cookieInfo
- });
- const cookieProperty = [
- {
- leftText: "name",
- rightText: cookieInfo.name
- },
- {
- leftText: "value",
- // 解码值
- rightText: Panel.getValue("decode-cookie-value") ? decodeURIComponent(cookieInfo.value) : encodeURIComponent(cookieInfo.value)
- }
- ];
- if (CookieManager.cookieManagerApiName === "GM_cookie" || 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*/
- `
- <div class="cookie-item-group-left">
- <p>${it.leftText}</p>
- </div>
- <div class="cookie-item-group-right">
- <p>${it.rightText}</p>
- </div>
- `
- )
- });
- domUtils.append($cookieItem, $cookieItemGroup);
- });
- let $cookieItemGroupControl = domUtils.createElement("div", {
- className: "cookie-item-group cookie-item-group-control",
- innerHTML: (
- /*html*/
- `
- <div class="cookie-item-group-left">操作</div>
- <div class="cookie-item-group-right">
- <div class="cookie-item-group-control-copy">
- <svg t="1742795616339" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
- <path d="M880 247.008l-162.016-166.016Q700.992 64 677.984 64h-316.992q-26.016 0-46.016 18.016-16.992 15.008-23.008 36.992H231.968q-43.008 0-73.504 31.008t-30.496 76v627.008q0 44 30.496 75.488T231.968 960h508q43.008 0 73.504-31.488t30.496-75.488v-63.008q23.008-6.016 37.504-25.504t14.496-44.512V287.008q0-24-16-40z m-168-160.992l-3.008-3.008z m98.016 177.984L744 196z m-126.016-116.992l108 110.016h-108V147.008zM676.992 128zM204.992 948q4 0.992 4.992 2.016-2.016-0.992-4.992-2.016z m27.008 4q-6.016 0-12-0.992 4.992 0.992 12 0.992z m543.008-99.008q0 15.008-10.016 25.504t-24.992 10.496H232q-14.016 0-24.512-10.496t-10.496-25.504V225.984q0-15.008 10.496-25.504t24.512-10.496h58.016v531.008q0 30.016 20.992 51.008t50.016 20.992H775.04v60z m52-132.992q0 2.016-2.016 2.016h-464q-2.016 0-2.016-2.016V136.992q0-2.016 2.016-2.016h251.008v156.992q0 15.008 10.016 24.992t24 10.016h180.992v392.992z m9.984 64q4-0.992 8.992-2.016-4.992 0.992-8.992 2.016z m-244-168.992h-107.008q-15.008 0-24.992 10.496t-10.016 24.992 10.016 24.992 24.992 10.496h107.008q14.016 0 24.512-10.496t10.496-24.992-10.496-24.992-24.512-10.496z m107.008-111.008h-214.016q-14.016 0-24.512 10.496t-10.496 24.992 10.496 24.992 24.512 10.496h214.016q14.016 0 24-10.496t10.016-24.992-10.016-24.992-24-10.496z m-240.992 36q0 4 0.992 8-0.992-4-0.992-8zM700 512z m12 52l4-2.016z m-260.992-135.488q0 14.496 10.496 24.992t24.512 10.496h214.016q14.016 0 24-10.496t10.016-24.992-10.016-24.992-24-10.496h-214.016q-14.016 0-24.512 10.496t-10.496 24.992z m8 1.504z"></path>
- </svg>
- </div>
- <div class="cookie-item-group-control-edit">
- <svg t="1742795710451" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
- <path d="M800 960 224 960c-52.928 0-96-43.072-96-96L128 224c0-52.928 43.072-96 96-96l448 0c17.696 0 32 14.336 32 32s-14.304 32-32 32L224 192C206.368 192 192 206.368 192 224l0 640c0 17.664 14.368 32 32 32l576 0c17.664 0 32-14.336 32-32L832 352c0-17.664 14.304-32 32-32s32 14.336 32 32l0 512C896 916.928 852.928 960 800 960zM612 448c-8.192 0-16.384-3.136-22.624-9.376-12.512-12.512-12.512-32.736 0-45.248l318.016-318.016c12.512-12.512 32.736-12.512 45.248 0s12.512 32.736 0 45.248l-318.016 318.016C628.384 444.896 620.192 448 612 448zM480 448 288 448c-17.664 0-32-14.336-32-32s14.336-32 32-32l192 0c17.664 0 32 14.336 32 32S497.664 448 480 448zM672 640 288 640c-17.664 0-32-14.304-32-32s14.336-32 32-32l384 0c17.696 0 32 14.304 32 32S689.696 640 672 640z"></path>
- </svg>
- </div>
- <div class="cookie-item-group-control-delete">
- ${__pops.config.iconSVG.delete}
- </div>
- </div>
- `
- )
- });
- 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__) => {
- let $newCookieItem = createCookieItemElement(__cookieInfo__);
- domUtils.after($cookieItem, $newCookieItem);
- $cookieItem.parentElement?.removeChild($cookieItem);
- });
- });
- domUtils.on($cookieItemDelete, "click", (event) => {
- utils.preventEvent(event);
- let result = confirm("确定删除该Cookie?");
- if (!result) {
- return;
- }
- CookieManager.deleteCookie(cookieInfo).then((status) => {
- if (!status) {
- Qmsg.success("删除成功");
- $cookieItem.parentElement?.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 (Panel.getValue("exclude-session-cookie")) {
- if (cookieItem.session) {
- return;
- }
- if (CookieManager.cookieManagerApiName === "cookieStore" && cookieItem.expires == null) {
- return;
- }
- }
- const $cookieItem = createCookieItemElement(cookieItem);
- $fragment.appendChild($cookieItem);
- });
- $cookieListWrapper.appendChild($fragment);
- };
- updateCookieListGroup();
- domUtils.on(
- $search,
- ["input", "propertychange"],
- utils.debounce((event) => {
- updateCookieListGroup((cookieItem) => {
- let searchText = domUtils.val($search);
- let enableRegExp = Panel.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 panelHandlerComponents = __pops.config.PanelHandlerComponents();
- let $useRegExp = panelHandlerComponents.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 && Panel.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 panelHandlerComponents = __pops.config.PanelHandlerComponents();
- let $useGM_cookie = panelHandlerComponents.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"
- },
- {
- text: "GM.cookie",
- value: "GM.cookie"
- }
- ],
- () => {
- updateCookieListGroup();
- },
- "操作Cookie的Api函数"
- )
- );
- let $decodeValue = panelHandlerComponents.createSectionContainerItem_switch(
- UISwitch(
- "解码Cookie值",
- "decode-cookie-value",
- false,
- () => {
- updateCookieListGroup();
- },
- "对Cookie值进行解码"
- )
- );
- let $excludeSessionCookie = panelHandlerComponents.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" || 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);
- }
- }
- }
- }
- });
- }
- }
- };
- const UIButton = function(text, description, buttonText, buttonIcon, buttonIsRightIcon, buttonIconIsLoading, buttonType, clickCallBack, afterAddToUListCallBack, disable) {
- let result = {
- text,
- type: "button",
- attributes: {},
- props: {},
- 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 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 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弹出的顺序"
- )
- ]
- }
- ]
- };
- PanelContent.addContentConfig([Component_Common, Component_Rule]);
- Panel.init();
- CookieRule.init();
- CookieRuleController.init();
- CookieManagerView.init();
- })(Qmsg, DOMUtils, Utils, pops);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址