CookieManager

简单而强大的Cookie编辑器,允许您快速创建、编辑和删除Cookie

  1. // ==UserScript==
  2. // @name CookieManager
  3. // @namespace https://github.com/WhiteSevs/TamperMonkeyScript
  4. // @version 2025.3.26
  5. // @author WhiteSevs
  6. // @description 简单而强大的Cookie编辑器,允许您快速创建、编辑和删除Cookie
  7. // @license GPL-3.0-only
  8. // @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==
  9. // @supportURL https://github.com/WhiteSevs/TamperMonkeyScript/issues
  10. // @match *://*/*
  11. // @require https://fastly.jsdelivr.net/gh/WhiteSevs/TamperMonkeyScript@86be74b83fca4fa47521cded28377b35e1d7d2ac/lib/CoverUMD/index.js
  12. // @require https://fastly.jsdelivr.net/npm/@whitesev/utils@2.6.4/dist/index.umd.js
  13. // @require https://fastly.jsdelivr.net/npm/@whitesev/domutils@1.5.1/dist/index.umd.js
  14. // @require https://fastly.jsdelivr.net/npm/@whitesev/pops@2.0.2/dist/index.umd.js
  15. // @require https://fastly.jsdelivr.net/npm/qmsg@1.3.0/dist/index.umd.js
  16. // @connect *
  17. // @grant GM_cookie
  18. // @grant GM_deleteValue
  19. // @grant GM_getValue
  20. // @grant GM_info
  21. // @grant GM_registerMenuCommand
  22. // @grant GM_setValue
  23. // @grant GM_unregisterMenuCommand
  24. // @grant GM_xmlhttpRequest
  25. // @grant unsafeWindow
  26. // @run-at document-start
  27. // ==/UserScript==
  28.  
  29. (function (Qmsg, DOMUtils, Utils, pops) {
  30. 'use strict';
  31.  
  32. var __defProp = Object.defineProperty;
  33. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  34. var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
  35. var _a;
  36. var _GM_cookie = /* @__PURE__ */ (() => typeof GM_cookie != "undefined" ? GM_cookie : void 0)();
  37. var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)();
  38. var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  39. var _GM_info = /* @__PURE__ */ (() => typeof GM_info != "undefined" ? GM_info : void 0)();
  40. var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
  41. var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  42. var _GM_unregisterMenuCommand = /* @__PURE__ */ (() => typeof GM_unregisterMenuCommand != "undefined" ? GM_unregisterMenuCommand : void 0)();
  43. var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
  44. var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
  45. var _monkeyWindow = /* @__PURE__ */ (() => window)();
  46. const PanelSettingConfig = {
  47. /** Toast位置 */
  48. qmsg_config_position: {
  49. key: "qmsg-config-position",
  50. defaultValue: "bottom"
  51. },
  52. /** 最多显示的数量 */
  53. qmsg_config_maxnums: {
  54. key: "qmsg-config-maxnums",
  55. defaultValue: 3
  56. },
  57. /** 逆序弹出 */
  58. qmsg_config_showreverse: {
  59. key: "qmsg-config-showreverse",
  60. defaultValue: false
  61. }
  62. };
  63. const _SCRIPT_NAME_ = "CookieManager";
  64. const utils = Utils.noConflict();
  65. const domUtils = DOMUtils.noConflict();
  66. const __pops = pops;
  67. const log = new utils.Log(
  68. _GM_info,
  69. _unsafeWindow.console || _monkeyWindow.console
  70. );
  71. const SCRIPT_NAME = ((_a = _GM_info == null ? void 0 : _GM_info.script) == null ? void 0 : _a.name) || _SCRIPT_NAME_;
  72. const DEBUG = false;
  73. log.config({
  74. debug: DEBUG,
  75. logMaxCount: 1e3,
  76. autoClearConsole: true,
  77. tag: true
  78. });
  79. Qmsg.config(
  80. Object.defineProperties(
  81. {
  82. html: true,
  83. autoClose: true,
  84. showClose: false
  85. },
  86. {
  87. position: {
  88. get() {
  89. return PopsPanel.getValue(
  90. PanelSettingConfig.qmsg_config_position.key,
  91. PanelSettingConfig.qmsg_config_position.defaultValue
  92. );
  93. }
  94. },
  95. maxNums: {
  96. get() {
  97. return PopsPanel.getValue(
  98. PanelSettingConfig.qmsg_config_maxnums.key,
  99. PanelSettingConfig.qmsg_config_maxnums.defaultValue
  100. );
  101. }
  102. },
  103. showReverse: {
  104. get() {
  105. return PopsPanel.getValue(
  106. PanelSettingConfig.qmsg_config_showreverse.key,
  107. PanelSettingConfig.qmsg_config_showreverse.defaultValue
  108. );
  109. }
  110. },
  111. zIndex: {
  112. get() {
  113. let maxZIndex = Utils.getMaxZIndex();
  114. let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex().zIndex;
  115. return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100;
  116. }
  117. }
  118. }
  119. )
  120. );
  121. __pops.GlobalConfig.setGlobalConfig({
  122. zIndex: () => {
  123. let maxZIndex = Utils.getMaxZIndex(void 0, void 0, ($ele) => {
  124. var _a2;
  125. if ((_a2 = $ele == null ? void 0 : $ele.classList) == null ? void 0 : _a2.contains("qmsg-shadow-container")) {
  126. return false;
  127. }
  128. if (($ele == null ? void 0 : $ele.closest("qmsg")) && $ele.getRootNode() instanceof ShadowRoot) {
  129. return false;
  130. }
  131. });
  132. let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex().zIndex;
  133. return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100;
  134. },
  135. mask: {
  136. // 开启遮罩层
  137. enable: true,
  138. // 取消点击遮罩层的事件
  139. clickEvent: {
  140. toClose: false,
  141. toHide: false
  142. }
  143. }
  144. });
  145. const GM_Menu = new utils.GM_Menu({
  146. GM_getValue: _GM_getValue,
  147. GM_setValue: _GM_setValue,
  148. GM_registerMenuCommand: _GM_registerMenuCommand,
  149. GM_unregisterMenuCommand: _GM_unregisterMenuCommand
  150. });
  151. const httpx = new utils.Httpx(_GM_xmlhttpRequest);
  152. httpx.interceptors.request.use((data) => {
  153. return data;
  154. });
  155. httpx.interceptors.response.use(void 0, (data) => {
  156. log.error("拦截器-请求错误", data);
  157. if (data.type === "onabort") {
  158. Qmsg.warning("请求取消");
  159. } else if (data.type === "onerror") {
  160. Qmsg.error("请求异常");
  161. } else if (data.type === "ontimeout") {
  162. Qmsg.error("请求超时");
  163. } else {
  164. Qmsg.error("其它错误");
  165. }
  166. return data;
  167. });
  168. httpx.config({
  169. logDetails: DEBUG
  170. });
  171. ({
  172. Object: {
  173. defineProperty: _unsafeWindow.Object.defineProperty
  174. },
  175. Function: {
  176. apply: _unsafeWindow.Function.prototype.apply,
  177. call: _unsafeWindow.Function.prototype.call
  178. },
  179. Element: {
  180. appendChild: _unsafeWindow.Element.prototype.appendChild
  181. },
  182. setTimeout: _unsafeWindow.setTimeout
  183. });
  184. utils.addStyle.bind(utils);
  185. document.querySelector.bind(document);
  186. document.querySelectorAll.bind(document);
  187. const utilsCookieManager = new Utils.GM_Cookie();
  188. const KEY = "GM_Panel";
  189. const ATTRIBUTE_INIT = "data-init";
  190. const ATTRIBUTE_KEY = "data-key";
  191. const ATTRIBUTE_DEFAULT_VALUE = "data-default-value";
  192. const ATTRIBUTE_INIT_MORE_VALUE = "data-init-more-value";
  193. const PROPS_STORAGE_API = "data-storage-api";
  194. const UISwitch = function(text, key, defaultValue, clickCallBack, description, afterAddToUListCallBack) {
  195. let result = {
  196. text,
  197. type: "switch",
  198. description,
  199. attributes: {},
  200. props: {},
  201. getValue() {
  202. return Boolean(
  203. this.props[PROPS_STORAGE_API].get(key, defaultValue)
  204. );
  205. },
  206. callback(event, __value) {
  207. let value = Boolean(__value);
  208. log.success(`${value ? "开启" : "关闭"} ${text}`);
  209. if (typeof clickCallBack === "function") {
  210. if (clickCallBack(event, value)) {
  211. return;
  212. }
  213. }
  214. this.props[PROPS_STORAGE_API].set(key, value);
  215. },
  216. afterAddToUListCallBack
  217. };
  218. Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
  219. Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
  220. Reflect.set(result.props, PROPS_STORAGE_API, {
  221. get(key2, defaultValue2) {
  222. return PopsPanel.getValue(key2, defaultValue2);
  223. },
  224. set(key2, value) {
  225. PopsPanel.setValue(key2, value);
  226. }
  227. });
  228. return result;
  229. };
  230. const UISelect = function(text, key, defaultValue, data, callback, description) {
  231. let selectData = [];
  232. if (typeof data === "function") {
  233. selectData = data();
  234. } else {
  235. selectData = data;
  236. }
  237. let result = {
  238. text,
  239. type: "select",
  240. description,
  241. attributes: {},
  242. props: {},
  243. getValue() {
  244. return this.props[PROPS_STORAGE_API].get(key, defaultValue);
  245. },
  246. callback(event, isSelectedValue, isSelectedText) {
  247. let value = isSelectedValue;
  248. log.info(`选择:${isSelectedText}`);
  249. this.props[PROPS_STORAGE_API].set(key, value);
  250. if (typeof callback === "function") {
  251. callback(event, value, isSelectedText);
  252. }
  253. },
  254. data: selectData
  255. };
  256. Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
  257. Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
  258. Reflect.set(result.props, PROPS_STORAGE_API, {
  259. get(key2, defaultValue2) {
  260. return PopsPanel.getValue(key2, defaultValue2);
  261. },
  262. set(key2, value) {
  263. PopsPanel.setValue(key2, value);
  264. }
  265. });
  266. return result;
  267. };
  268. const Component_Common = {
  269. id: "view-general",
  270. title: "通用",
  271. forms: [
  272. {
  273. text: "Toast配置",
  274. type: "forms",
  275. forms: [
  276. UISelect(
  277. "Toast位置",
  278. PanelSettingConfig.qmsg_config_position.key,
  279. PanelSettingConfig.qmsg_config_position.defaultValue,
  280. [
  281. {
  282. value: "topleft",
  283. text: "左上角"
  284. },
  285. {
  286. value: "top",
  287. text: "顶部"
  288. },
  289. {
  290. value: "topright",
  291. text: "右上角"
  292. },
  293. {
  294. value: "left",
  295. text: "左边"
  296. },
  297. {
  298. value: "center",
  299. text: "中间"
  300. },
  301. {
  302. value: "right",
  303. text: "右边"
  304. },
  305. {
  306. value: "bottomleft",
  307. text: "左下角"
  308. },
  309. {
  310. value: "bottom",
  311. text: "底部"
  312. },
  313. {
  314. value: "bottomright",
  315. text: "右下角"
  316. }
  317. ],
  318. (event, isSelectValue, isSelectText) => {
  319. log.info("设置当前Qmsg弹出位置" + isSelectText);
  320. },
  321. "Toast显示在页面九宫格的位置"
  322. ),
  323. UISelect(
  324. "最多显示的数量",
  325. PanelSettingConfig.qmsg_config_maxnums.key,
  326. PanelSettingConfig.qmsg_config_maxnums.defaultValue,
  327. [
  328. {
  329. value: 1,
  330. text: "1"
  331. },
  332. {
  333. value: 2,
  334. text: "2"
  335. },
  336. {
  337. value: 3,
  338. text: "3"
  339. },
  340. {
  341. value: 4,
  342. text: "4"
  343. },
  344. {
  345. value: 5,
  346. text: "5"
  347. }
  348. ],
  349. void 0,
  350. "限制Toast显示的数量"
  351. ),
  352. UISwitch(
  353. "逆序弹出",
  354. PanelSettingConfig.qmsg_config_showreverse.key,
  355. PanelSettingConfig.qmsg_config_showreverse.defaultValue,
  356. void 0,
  357. "修改Toast弹出的顺序"
  358. )
  359. ]
  360. }
  361. ]
  362. };
  363. const PanelUISize = {
  364. /**
  365. * 一般设置界面的尺寸
  366. */
  367. setting: {
  368. get width() {
  369. return window.innerWidth < 550 ? "88vw" : "550px";
  370. },
  371. get height() {
  372. return window.innerHeight < 450 ? "70vh" : "450px";
  373. }
  374. },
  375. /**
  376. * 信息界面,一般用于提示信息之类
  377. */
  378. info: {
  379. get width() {
  380. return window.innerWidth < 350 ? "350px" : "350px";
  381. },
  382. get height() {
  383. return window.innerHeight < 250 ? "250px" : "250px";
  384. }
  385. }
  386. };
  387. const UIButton = function(text, description, buttonText, buttonIcon, buttonIsRightIcon, buttonIconIsLoading, buttonType, clickCallBack, afterAddToUListCallBack, disable) {
  388. let result = {
  389. text,
  390. type: "button",
  391. attributes: {},
  392. description,
  393. buttonIcon,
  394. buttonIsRightIcon,
  395. buttonIconIsLoading,
  396. buttonType,
  397. buttonText,
  398. callback(event) {
  399. if (typeof clickCallBack === "function") {
  400. clickCallBack(event);
  401. }
  402. },
  403. afterAddToUListCallBack
  404. };
  405. Reflect.set(result.attributes, ATTRIBUTE_INIT, () => {
  406. result.disable = Boolean(
  407. disable
  408. );
  409. });
  410. return result;
  411. };
  412. const UIInput = function(text, key, defaultValue, description, changeCallBack, placeholder = "", isNumber, isPassword) {
  413. let result = {
  414. text,
  415. type: "input",
  416. isNumber: Boolean(isNumber),
  417. isPassword: Boolean(isPassword),
  418. props: {},
  419. attributes: {},
  420. description,
  421. getValue() {
  422. return this.props[PROPS_STORAGE_API].get(key, defaultValue);
  423. },
  424. callback(event, value) {
  425. this.props[PROPS_STORAGE_API].set(key, value);
  426. },
  427. placeholder
  428. };
  429. Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
  430. Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
  431. Reflect.set(result.props, PROPS_STORAGE_API, {
  432. get(key2, defaultValue2) {
  433. return PopsPanel.getValue(key2, defaultValue2);
  434. },
  435. set(key2, value) {
  436. PopsPanel.setValue(key2, value);
  437. }
  438. });
  439. return result;
  440. };
  441. const UITextArea = function(text, key, defaultValue, description, changeCallBack, placeholder = "", disabled) {
  442. let result = {
  443. text,
  444. type: "textarea",
  445. attributes: {},
  446. props: {},
  447. description,
  448. placeholder,
  449. disabled,
  450. getValue() {
  451. let value = this.props[PROPS_STORAGE_API].get(key, defaultValue);
  452. if (Array.isArray(value)) {
  453. return value.join("\n");
  454. }
  455. return value;
  456. },
  457. callback(event, value) {
  458. this.props[PROPS_STORAGE_API].set(key, value);
  459. }
  460. };
  461. Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
  462. Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
  463. Reflect.set(result.props, PROPS_STORAGE_API, {
  464. get(key2, defaultValue2) {
  465. return PopsPanel.getValue(key2, defaultValue2);
  466. },
  467. set(key2, value) {
  468. PopsPanel.setValue(key2, value);
  469. }
  470. });
  471. return result;
  472. };
  473. class RuleEditView {
  474. constructor(option) {
  475. __publicField(this, "option");
  476. this.option = option;
  477. }
  478. /**
  479. * 显示视图
  480. */
  481. async showView() {
  482. var _a2;
  483. let $dialog = __pops.confirm({
  484. title: {
  485. text: this.option.title,
  486. position: "center"
  487. },
  488. content: {
  489. text: (
  490. /*html*/
  491. `
  492. <form class="rule-form-container" onsubmit="return false">
  493. <ul class="rule-form-ulist">
  494. </ul>
  495. <input type="submit" style="display: none;" />
  496. </form>
  497. `
  498. ),
  499. html: true
  500. },
  501. btn: utils.assign(
  502. {
  503. ok: {
  504. callback: async () => {
  505. await submitSaveOption();
  506. }
  507. }
  508. },
  509. this.option.btn || {},
  510. true
  511. ),
  512. mask: {
  513. enable: true
  514. },
  515. drag: true,
  516. style: (
  517. /*css*/
  518. `
  519. ${__pops.config.cssText.panelCSS}
  520. .rule-form-container {
  521. }
  522. .rule-form-container li{
  523. display: flex;
  524. align-items: center;
  525. justify-content: space-between;
  526. padding: 5px 20px;
  527. gap: 10px;
  528. }
  529. .pops-panel-item-left-main-text{
  530. max-width: 150px;
  531. }
  532. .pops-panel-item-right-text{
  533. padding-left: 30px;
  534. }
  535. .pops-panel-item-right-text,
  536. .pops-panel-item-right-main-text{
  537. text-overflow: ellipsis;
  538. overflow: hidden;
  539. white-space: nowrap;
  540. }
  541.  
  542. ${((_a2 = this.option) == null ? void 0 : _a2.style) ?? ""}
  543. `
  544. ),
  545. width: typeof this.option.width === "function" ? this.option.width() : window.innerWidth > 500 ? "500px" : "88vw",
  546. height: typeof this.option.height === "function" ? this.option.height() : window.innerHeight > 500 ? "500px" : "80vh"
  547. });
  548. let $form = $dialog.$shadowRoot.querySelector(
  549. ".rule-form-container"
  550. );
  551. $dialog.$shadowRoot.querySelector(
  552. "input[type=submit]"
  553. );
  554. let $ulist = $dialog.$shadowRoot.querySelector(".rule-form-ulist");
  555. let view = await this.option.getView(await this.option.data());
  556. $ulist.appendChild(view);
  557. const submitSaveOption = async () => {
  558. let result = await this.option.onsubmit($form, await this.option.data());
  559. if (!result.success) {
  560. return;
  561. }
  562. $dialog.close();
  563. await this.option.dialogCloseCallBack(true);
  564. };
  565. }
  566. }
  567. class RuleFilterView {
  568. constructor(option) {
  569. __publicField(this, "option");
  570. this.option = option;
  571. }
  572. showView() {
  573. let $alert = __pops.alert({
  574. title: {
  575. text: this.option.title,
  576. position: "center"
  577. },
  578. content: {
  579. text: (
  580. /*html*/
  581. `
  582. <div class="filter-container"></div>
  583. `
  584. )
  585. },
  586. btn: {
  587. ok: {
  588. text: "关闭",
  589. type: "default"
  590. }
  591. },
  592. mask: {
  593. enable: true
  594. },
  595. width: window.innerWidth > 500 ? "350px" : "80vw",
  596. height: window.innerHeight > 500 ? "300px" : "70vh",
  597. style: (
  598. /*css*/
  599. `
  600. .filter-container{
  601. height: 100%;
  602. display: flex;
  603. flex-direction: column;
  604. gap: 20px;
  605. }
  606. .filter-container button{
  607. text-wrap: wrap;
  608. padding: 8px;
  609. height: auto;
  610. text-align: left;
  611. }
  612. `
  613. )
  614. });
  615. let $filterContainer = $alert.$shadowRoot.querySelector(".filter-container");
  616. let $fragment = document.createDocumentFragment();
  617. this.option.filterOption.forEach((filterOption) => {
  618. let $button = document.createElement("button");
  619. $button.innerText = filterOption.name;
  620. let execFilterAndCloseDialog = async () => {
  621. let allRuleInfo = await this.option.getAllRuleInfo();
  622. allRuleInfo.forEach(async (ruleInfo) => {
  623. let filterResult = await filterOption.filterCallBack(ruleInfo.data);
  624. if (!filterResult) {
  625. domUtils.hide(ruleInfo.$el, false);
  626. } else {
  627. domUtils.show(ruleInfo.$el, false);
  628. }
  629. });
  630. if (typeof this.option.execFilterCallBack === "function") {
  631. await this.option.execFilterCallBack();
  632. }
  633. $alert.close();
  634. };
  635. domUtils.on($button, "click", async (event) => {
  636. utils.preventEvent(event);
  637. if (typeof filterOption.callback === "function") {
  638. let result = await filterOption.callback(
  639. event,
  640. execFilterAndCloseDialog
  641. );
  642. if (!result) {
  643. return;
  644. }
  645. }
  646. await execFilterAndCloseDialog();
  647. });
  648. $fragment.appendChild($button);
  649. });
  650. $filterContainer.appendChild($fragment);
  651. }
  652. }
  653. class RuleView {
  654. constructor(option) {
  655. __publicField(this, "option");
  656. this.option = option;
  657. }
  658. /**
  659. * 显示视图
  660. * @param filterCallBack 返回值为false隐藏,true则不隐藏(不处理)
  661. */
  662. async showView(filterCallBack) {
  663. var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
  664. let $popsConfirm = __pops.confirm({
  665. title: {
  666. text: this.option.title,
  667. position: "center"
  668. },
  669. content: {
  670. text: (
  671. /*html*/
  672. `
  673. <div class="rule-view-container">
  674. </div>
  675. `
  676. ),
  677. html: true
  678. },
  679. btn: {
  680. merge: true,
  681. reverse: false,
  682. position: "space-between",
  683. ok: {
  684. enable: ((_c = (_b = (_a2 = this.option) == null ? void 0 : _a2.bottomControls) == null ? void 0 : _b.add) == null ? void 0 : _c.enable) || true,
  685. type: "primary",
  686. text: "添加",
  687. callback: async (event) => {
  688. this.showEditView(
  689. false,
  690. await this.option.getAddData(),
  691. $popsConfirm.$shadowRoot
  692. );
  693. }
  694. },
  695. close: {
  696. enable: true,
  697. callback(event) {
  698. $popsConfirm.close();
  699. }
  700. },
  701. cancel: {
  702. enable: ((_f = (_e = (_d = this.option) == null ? void 0 : _d.bottomControls) == null ? void 0 : _e.filter) == null ? void 0 : _f.enable) || false,
  703. type: "default",
  704. text: "过滤",
  705. callback: (details, event) => {
  706. var _a3, _b2, _c2, _d2, _e2, _f2, _g2;
  707. if (typeof ((_c2 = (_b2 = (_a3 = this.option) == null ? void 0 : _a3.bottomControls) == null ? void 0 : _b2.filter) == null ? void 0 : _c2.callback) === "function") {
  708. this.option.bottomControls.filter.callback();
  709. }
  710. let getAllRuleElement = () => {
  711. return Array.from(
  712. $popsConfirm.$shadowRoot.querySelectorAll(
  713. ".rule-view-container .rule-item"
  714. )
  715. );
  716. };
  717. let $button = event.target.closest(".pops-confirm-btn").querySelector(".pops-confirm-btn-cancel span");
  718. if (domUtils.text($button).includes("取消")) {
  719. getAllRuleElement().forEach(($el) => {
  720. domUtils.show($el, false);
  721. });
  722. domUtils.text($button, "过滤");
  723. } else {
  724. let ruleFilterView = new RuleFilterView({
  725. title: ((_e2 = (_d2 = this.option.bottomControls) == null ? void 0 : _d2.filter) == null ? void 0 : _e2.title) ?? "过滤规则",
  726. filterOption: ((_g2 = (_f2 = this.option.bottomControls) == null ? void 0 : _f2.filter) == null ? void 0 : _g2.option) || [],
  727. execFilterCallBack() {
  728. domUtils.text($button, "取消过滤");
  729. },
  730. getAllRuleInfo: () => {
  731. return getAllRuleElement().map(($el) => {
  732. return {
  733. data: this.parseRuleItemElement($el).data,
  734. $el
  735. };
  736. });
  737. }
  738. });
  739. ruleFilterView.showView();
  740. }
  741. }
  742. },
  743. other: {
  744. enable: ((_i = (_h = (_g = this.option) == null ? void 0 : _g.bottomControls) == null ? void 0 : _h.clear) == null ? void 0 : _i.enable) || true,
  745. type: "xiaomi-primary",
  746. text: `清空所有(${(await this.option.data()).length})`,
  747. callback: (event) => {
  748. let $askDialog = __pops.confirm({
  749. title: {
  750. text: "提示",
  751. position: "center"
  752. },
  753. content: {
  754. text: "确定清空所有的数据?",
  755. html: false
  756. },
  757. btn: {
  758. ok: {
  759. enable: true,
  760. callback: async (popsEvent) => {
  761. var _a3, _b2, _c2;
  762. log.success("清空所有");
  763. if (typeof ((_c2 = (_b2 = (_a3 = this.option) == null ? void 0 : _a3.bottomControls) == null ? void 0 : _b2.clear) == null ? void 0 : _c2.callback) === "function") {
  764. this.option.bottomControls.clear.callback();
  765. }
  766. let data = await this.option.data();
  767. if (data.length) {
  768. Qmsg.error("清理失败");
  769. return;
  770. } else {
  771. Qmsg.success("清理成功");
  772. }
  773. await this.updateDeleteAllBtnText($popsConfirm.$shadowRoot);
  774. this.clearContent($popsConfirm.$shadowRoot);
  775. $askDialog.close();
  776. }
  777. },
  778. cancel: {
  779. text: "取消",
  780. enable: true
  781. }
  782. },
  783. mask: { enable: true },
  784. width: "300px",
  785. height: "200px"
  786. });
  787. }
  788. }
  789. },
  790. mask: {
  791. enable: true
  792. },
  793. drag: true,
  794. width: window.innerWidth > 500 ? "500px" : "88vw",
  795. height: window.innerHeight > 500 ? "500px" : "80vh",
  796. style: (
  797. /*css*/
  798. `
  799. ${__pops.config.cssText.panelCSS}
  800. .rule-item{
  801. display: flex;
  802. align-items: center;
  803. line-height: normal;
  804. font-size: 16px;
  805. padding: 4px 8px;
  806. gap: 8px;
  807. }
  808. .rule-name{
  809. flex: 1;
  810. white-space: nowrap;
  811. text-overflow: ellipsis;
  812. overflow: hidden;
  813. }
  814. .rule-controls{
  815. display: flex;
  816. align-items: center;
  817. text-overflow: ellipsis;
  818. overflow: hidden;
  819. white-space: nowrap;
  820. gap: 8px;
  821. padding: 0px;
  822. }
  823. .rule-controls-enable{
  824. }
  825. .rule-controls-edit{
  826. }
  827. .rule-controls-delete{
  828. }
  829. .rule-controls-edit,
  830. .rule-controls-delete{
  831. width: 16px;
  832. height: 16px;
  833. cursor: pointer;
  834. }
  835. `
  836. )
  837. });
  838. let allData = await this.option.data();
  839. let changeButtonText = false;
  840. for (let index = 0; index < allData.length; index++) {
  841. let item = allData[index];
  842. let $ruleItemList = await this.appendRuleItemElement(
  843. $popsConfirm.$shadowRoot,
  844. item
  845. );
  846. let flag = typeof filterCallBack === "function" ? filterCallBack(item) : true;
  847. if (!flag) {
  848. changeButtonText = true;
  849. $ruleItemList.forEach(($el) => {
  850. domUtils.hide($el, false);
  851. });
  852. }
  853. }
  854. if (changeButtonText) {
  855. let $button = $popsConfirm.$shadowRoot.querySelector(
  856. ".pops-confirm-btn-cancel span"
  857. );
  858. domUtils.text($button, "取消过滤");
  859. }
  860. }
  861. /**
  862. * 显示编辑视图
  863. * @param isEdit 是否是编辑状态
  864. * @param editData 编辑的数据
  865. * @param $parentShadowRoot (可选)关闭弹窗后对ShadowRoot进行操作
  866. * @param $editRuleItemElement (可选)关闭弹窗后对规则行进行更新数据
  867. * @param updateDataCallBack (可选)关闭添加/编辑弹窗的回调(不更新数据)
  868. * @param submitCallBack (可选)添加/修改提交的回调
  869. */
  870. showEditView(isEdit, editData, $parentShadowRoot, $editRuleItemElement, updateDataCallBack, submitCallBack) {
  871. let dialogCloseCallBack = async (isSubmit) => {
  872. if (isSubmit) {
  873. if (typeof submitCallBack === "function") {
  874. let newData = await this.option.getData(editData);
  875. submitCallBack(newData);
  876. }
  877. } else {
  878. if (!isEdit) {
  879. await this.option.deleteData(editData);
  880. }
  881. if (typeof updateDataCallBack === "function") {
  882. let newData = await this.option.getData(editData);
  883. updateDataCallBack(newData);
  884. }
  885. }
  886. };
  887. let editView = new RuleEditView({
  888. title: isEdit ? "编辑" : "添加",
  889. data: () => {
  890. return editData;
  891. },
  892. dialogCloseCallBack,
  893. getView: async (data) => {
  894. return await this.option.itemControls.edit.getView(data, isEdit);
  895. },
  896. btn: {
  897. ok: {
  898. enable: true,
  899. text: isEdit ? "修改" : "添加"
  900. },
  901. cancel: {
  902. callback: async (detail, event) => {
  903. detail.close();
  904. await dialogCloseCallBack(false);
  905. }
  906. },
  907. close: {
  908. callback: async (detail, event) => {
  909. detail.close();
  910. await dialogCloseCallBack(false);
  911. }
  912. }
  913. },
  914. onsubmit: async ($form, data) => {
  915. let result = await this.option.itemControls.edit.onsubmit(
  916. $form,
  917. isEdit,
  918. data
  919. );
  920. if (result.success) {
  921. if (isEdit) {
  922. Qmsg.success("修改成功");
  923. $parentShadowRoot && await this.updateRuleItemElement(
  924. result.data,
  925. $editRuleItemElement,
  926. $parentShadowRoot
  927. );
  928. } else {
  929. $parentShadowRoot && await this.appendRuleItemElement(
  930. $parentShadowRoot,
  931. result.data
  932. );
  933. }
  934. } else {
  935. if (isEdit) {
  936. Qmsg.error("修改失败");
  937. }
  938. }
  939. return result;
  940. },
  941. style: this.option.itemControls.edit.style,
  942. width: this.option.itemControls.edit.width,
  943. height: this.option.itemControls.edit.height
  944. });
  945. editView.showView();
  946. }
  947. /**
  948. * 解析弹窗内的各个元素
  949. */
  950. parseViewElement($shadowRoot) {
  951. let $container = $shadowRoot.querySelector(
  952. ".rule-view-container"
  953. );
  954. let $deleteBtn = $shadowRoot.querySelector(
  955. ".pops-confirm-btn button.pops-confirm-btn-other"
  956. );
  957. return {
  958. /** 容器 */
  959. $container,
  960. /** 左下角的清空按钮 */
  961. $deleteBtn
  962. };
  963. }
  964. /**
  965. * 解析每一项的元素
  966. */
  967. parseRuleItemElement($ruleElement) {
  968. let $enable = $ruleElement.querySelector(
  969. ".rule-controls-enable"
  970. );
  971. let $enableSwitch = $enable.querySelector(".pops-panel-switch");
  972. let $enableSwitchInput = $enable.querySelector(
  973. ".pops-panel-switch__input"
  974. );
  975. let $enableSwitchCore = $enable.querySelector(
  976. ".pops-panel-switch__core"
  977. );
  978. let $edit = $ruleElement.querySelector(".rule-controls-edit");
  979. let $delete = $ruleElement.querySelector(
  980. ".rule-controls-delete"
  981. );
  982. return {
  983. /** 启用开关 */
  984. $enable,
  985. /** 启用开关的container */
  986. $enableSwitch,
  987. /** 启用开关的input */
  988. $enableSwitchInput,
  989. /** 启用开关的core */
  990. $enableSwitchCore,
  991. /** 编辑按钮 */
  992. $edit,
  993. /** 删除按钮 */
  994. $delete,
  995. /** 存储在元素上的数据 */
  996. data: Reflect.get($ruleElement, "data-rule")
  997. };
  998. }
  999. /**
  1000. * 创建一条规则元素
  1001. */
  1002. async createRuleItemElement(data, $shadowRoot) {
  1003. let name = await this.option.getDataItemName(data);
  1004. let $ruleItem = domUtils.createElement("div", {
  1005. className: "rule-item",
  1006. innerHTML: (
  1007. /*html*/
  1008. `
  1009. <div class="rule-name">${name}</div>
  1010. <div class="rule-controls">
  1011. <div class="rule-controls-enable">
  1012. <div class="pops-panel-switch">
  1013. <input class="pops-panel-switch__input" type="checkbox">
  1014. <span class="pops-panel-switch__core">
  1015. <div class="pops-panel-switch__action">
  1016. </div>
  1017. </span>
  1018. </div>
  1019. </div>
  1020. <div class="rule-controls-edit">
  1021. ${__pops.config.iconSVG.edit}
  1022. </div>
  1023. <div class="rule-controls-delete">
  1024. ${__pops.config.iconSVG.delete}
  1025. </div>
  1026. </div>
  1027. `
  1028. )
  1029. });
  1030. Reflect.set($ruleItem, "data-rule", data);
  1031. let switchCheckedClassName = "pops-panel-switch-is-checked";
  1032. const {
  1033. $enable,
  1034. $enableSwitch,
  1035. $enableSwitchCore,
  1036. $enableSwitchInput,
  1037. $delete,
  1038. $edit
  1039. } = this.parseRuleItemElement($ruleItem);
  1040. if (this.option.itemControls.enable.enable) {
  1041. domUtils.on($enableSwitchCore, "click", async (event) => {
  1042. let isChecked = false;
  1043. if ($enableSwitch.classList.contains(switchCheckedClassName)) {
  1044. $enableSwitch.classList.remove(switchCheckedClassName);
  1045. isChecked = false;
  1046. } else {
  1047. $enableSwitch.classList.add(switchCheckedClassName);
  1048. isChecked = true;
  1049. }
  1050. $enableSwitchInput.checked = isChecked;
  1051. await this.option.itemControls.enable.callback(data, isChecked);
  1052. });
  1053. if (await this.option.itemControls.enable.getEnable(data)) {
  1054. $enableSwitch.classList.add(switchCheckedClassName);
  1055. }
  1056. } else {
  1057. $enable.remove();
  1058. }
  1059. if (this.option.itemControls.edit.enable) {
  1060. domUtils.on($edit, "click", (event) => {
  1061. utils.preventEvent(event);
  1062. this.showEditView(true, data, $shadowRoot, $ruleItem, (newData) => {
  1063. data = null;
  1064. data = newData;
  1065. });
  1066. });
  1067. } else {
  1068. $edit.remove();
  1069. }
  1070. if (this.option.itemControls.delete.enable) {
  1071. domUtils.on($delete, "click", (event) => {
  1072. utils.preventEvent(event);
  1073. let $askDialog = __pops.confirm({
  1074. title: {
  1075. text: "提示",
  1076. position: "center"
  1077. },
  1078. content: {
  1079. text: "确定删除该条数据?",
  1080. html: false
  1081. },
  1082. btn: {
  1083. ok: {
  1084. enable: true,
  1085. callback: async (popsEvent) => {
  1086. log.success("删除数据");
  1087. let flag = await this.option.itemControls.delete.deleteCallBack(
  1088. data
  1089. );
  1090. if (flag) {
  1091. Qmsg.success("成功删除该数据");
  1092. $ruleItem.remove();
  1093. await this.updateDeleteAllBtnText($shadowRoot);
  1094. $askDialog.close();
  1095. } else {
  1096. Qmsg.error("删除该数据失败");
  1097. }
  1098. }
  1099. },
  1100. cancel: {
  1101. text: "取消",
  1102. enable: true
  1103. }
  1104. },
  1105. mask: {
  1106. enable: true
  1107. },
  1108. width: "300px",
  1109. height: "200px"
  1110. });
  1111. });
  1112. } else {
  1113. $delete.remove();
  1114. }
  1115. return $ruleItem;
  1116. }
  1117. /**
  1118. * 添加一个规则元素
  1119. */
  1120. async appendRuleItemElement($shadowRoot, data) {
  1121. let { $container } = this.parseViewElement($shadowRoot);
  1122. let $ruleItem = [];
  1123. let iteratorData = Array.isArray(data) ? data : [data];
  1124. for (let index = 0; index < iteratorData.length; index++) {
  1125. let item = iteratorData[index];
  1126. let $item = await this.createRuleItemElement(item, $shadowRoot);
  1127. $container.appendChild($item);
  1128. $ruleItem.push($item);
  1129. }
  1130. await this.updateDeleteAllBtnText($shadowRoot);
  1131. return $ruleItem;
  1132. }
  1133. /**
  1134. * 更新弹窗内容的元素
  1135. */
  1136. async updateRuleContaienrElement($shadowRoot) {
  1137. this.clearContent($shadowRoot);
  1138. const { $container } = this.parseViewElement($shadowRoot);
  1139. let data = await this.option.data();
  1140. await this.appendRuleItemElement($shadowRoot, data);
  1141. await this.updateDeleteAllBtnText($shadowRoot);
  1142. }
  1143. /**
  1144. * 更新规则元素
  1145. */
  1146. async updateRuleItemElement(data, $oldRuleItem, $shadowRoot) {
  1147. let $newRuleItem = await this.createRuleItemElement(data, $shadowRoot);
  1148. $oldRuleItem.after($newRuleItem);
  1149. $oldRuleItem.remove();
  1150. }
  1151. /**
  1152. * 清空内容
  1153. */
  1154. clearContent($shadowRoot) {
  1155. const { $container } = this.parseViewElement($shadowRoot);
  1156. domUtils.html($container, "");
  1157. }
  1158. /**
  1159. * 设置删除按钮的文字
  1160. */
  1161. setDeleteBtnText($shadowRoot, text, isHTML = false) {
  1162. const { $deleteBtn } = this.parseViewElement($shadowRoot);
  1163. if (isHTML) {
  1164. domUtils.html($deleteBtn, text);
  1165. } else {
  1166. domUtils.text($deleteBtn, text);
  1167. }
  1168. }
  1169. /**
  1170. * 更新【清空所有】的按钮的文字
  1171. * @param $shadowRoot
  1172. */
  1173. async updateDeleteAllBtnText($shadowRoot) {
  1174. let data = await this.option.data();
  1175. this.setDeleteBtnText($shadowRoot, `清空所有(${data.length})`);
  1176. }
  1177. }
  1178. const CookieRule = {
  1179. $key: {
  1180. STORAGE_KEY: "cookie-rule"
  1181. },
  1182. $data: {
  1183. /** 规则数据 */
  1184. ruleData: []
  1185. },
  1186. /** 初始化数据 */
  1187. init() {
  1188. this.$data.ruleData = [];
  1189. let allData = this.getData();
  1190. allData.forEach((data) => {
  1191. if (!data.enable) {
  1192. return;
  1193. }
  1194. let url = window.location.href;
  1195. let ruleUrl = data.data.url;
  1196. let enableRegExpToMatchUrl = data.data.enableRegExpToMatchUrl;
  1197. if (enableRegExpToMatchUrl) {
  1198. let regExpUrl = new RegExp(ruleUrl, "i");
  1199. if (!regExpUrl.test(url)) {
  1200. return;
  1201. }
  1202. } else {
  1203. if (!url.includes(ruleUrl)) {
  1204. return;
  1205. }
  1206. }
  1207. this.$data.ruleData.push(data);
  1208. });
  1209. },
  1210. /**
  1211. * 显示视图
  1212. */
  1213. showView() {
  1214. let popsPanelContentUtils = __pops.config.panelHandleContentUtils();
  1215. function generateStorageApi(data, handler) {
  1216. return {
  1217. get(key, defaultValue) {
  1218. return Reflect.get(data, key) ?? defaultValue;
  1219. },
  1220. set(key, value) {
  1221. Reflect.set(data, key, value);
  1222. }
  1223. };
  1224. }
  1225. let ruleView = new RuleView({
  1226. title: "Cookie规则",
  1227. data: () => {
  1228. return this.getData();
  1229. },
  1230. getAddData: () => {
  1231. return this.getTemplateData();
  1232. },
  1233. getDataItemName: (data) => {
  1234. return data["name"];
  1235. },
  1236. updateData: (data) => {
  1237. return this.updateData(data);
  1238. },
  1239. deleteData: (data) => {
  1240. return this.deleteData(data);
  1241. },
  1242. getData: (data) => {
  1243. let allData = this.getData();
  1244. let findValue = allData.find((item) => item.uuid === data.uuid);
  1245. return findValue ?? data;
  1246. },
  1247. itemControls: {
  1248. enable: {
  1249. enable: true,
  1250. getEnable(data) {
  1251. return data.enable;
  1252. },
  1253. callback: (data, enable) => {
  1254. data.enable = enable;
  1255. this.updateData(data);
  1256. }
  1257. },
  1258. edit: {
  1259. enable: true,
  1260. getView: (data, isEdit) => {
  1261. let $fragment = document.createDocumentFragment();
  1262. let templateData = this.getTemplateData();
  1263. if (!isEdit) {
  1264. data = templateData;
  1265. }
  1266. let enable_template = UISwitch(
  1267. "启用",
  1268. "enable",
  1269. templateData.enable
  1270. );
  1271. Reflect.set(
  1272. enable_template.props,
  1273. PROPS_STORAGE_API,
  1274. generateStorageApi(data)
  1275. );
  1276. let $enable = popsPanelContentUtils.createSectionContainerItem_switch(
  1277. enable_template
  1278. );
  1279. let name_template = UIInput(
  1280. "规则名称",
  1281. "name",
  1282. "",
  1283. templateData.name,
  1284. void 0,
  1285. "必填"
  1286. );
  1287. Reflect.set(
  1288. name_template.props,
  1289. PROPS_STORAGE_API,
  1290. generateStorageApi(data)
  1291. );
  1292. let $name = popsPanelContentUtils.createSectionContainerItem_input(
  1293. name_template
  1294. );
  1295. let url_template = UIInput(
  1296. "网址",
  1297. "url",
  1298. templateData.data.url,
  1299. "用于执行该规则的网址",
  1300. void 0,
  1301. "必填"
  1302. );
  1303. Reflect.set(
  1304. url_template.props,
  1305. PROPS_STORAGE_API,
  1306. generateStorageApi(data.data)
  1307. );
  1308. let $url = popsPanelContentUtils.createSectionContainerItem_input(
  1309. url_template
  1310. );
  1311. let enableRegExpToMatchUrl_template = UISwitch(
  1312. "启用正则匹配网址",
  1313. "enableRegExpToMatchUrl",
  1314. templateData.data.enableRegExpToMatchUrl
  1315. );
  1316. Reflect.set(
  1317. enableRegExpToMatchUrl_template.props,
  1318. PROPS_STORAGE_API,
  1319. generateStorageApi(data.data)
  1320. );
  1321. let $enableRegExpToMatchUrl = popsPanelContentUtils.createSectionContainerItem_switch(
  1322. enableRegExpToMatchUrl_template
  1323. );
  1324. let cookieName_template = UIInput(
  1325. "Cookie名称",
  1326. "cookieName",
  1327. templateData.data.cookieName,
  1328. "用于匹配执行操作的Cookie名",
  1329. void 0,
  1330. "必填"
  1331. );
  1332. Reflect.set(
  1333. cookieName_template.props,
  1334. PROPS_STORAGE_API,
  1335. generateStorageApi(data.data)
  1336. );
  1337. let $cookieName = popsPanelContentUtils.createSectionContainerItem_input(
  1338. cookieName_template
  1339. );
  1340. let enableRegExpToMatchCookieName_template = UISwitch(
  1341. "启用正则匹配Cookie名称",
  1342. "enableRegExpToMatchCookieName",
  1343. templateData.data.enableRegExpToMatchCookieName
  1344. );
  1345. Reflect.set(
  1346. enableRegExpToMatchCookieName_template.props,
  1347. PROPS_STORAGE_API,
  1348. generateStorageApi(data.data)
  1349. );
  1350. let $enableRegExpToMatchCookieName = popsPanelContentUtils.createSectionContainerItem_switch(
  1351. enableRegExpToMatchCookieName_template
  1352. );
  1353. let operationMode_template = UISelect(
  1354. "操作模式",
  1355. "operationMode",
  1356. templateData.data.operationMode,
  1357. [
  1358. {
  1359. value: "delete",
  1360. text: "删除Cookie"
  1361. },
  1362. {
  1363. value: "extended",
  1364. text: "自动延长Cookie有效期30天"
  1365. },
  1366. {
  1367. value: "extended-90",
  1368. text: "自动延长Cookie有效期90天"
  1369. },
  1370. {
  1371. value: "extended-180",
  1372. text: "自动延长Cookie有效期180天"
  1373. },
  1374. {
  1375. value: "extended-360",
  1376. text: "自动延长Cookie有效期360天"
  1377. }
  1378. ]
  1379. );
  1380. Reflect.set(
  1381. operationMode_template.props,
  1382. PROPS_STORAGE_API,
  1383. generateStorageApi(data.data)
  1384. );
  1385. let $operationMode = popsPanelContentUtils.createSectionContainerItem_select(
  1386. operationMode_template
  1387. );
  1388. let remark_template = UITextArea(
  1389. "备注",
  1390. "remark",
  1391. templateData.data.remark
  1392. );
  1393. Reflect.set(
  1394. remark_template.props,
  1395. PROPS_STORAGE_API,
  1396. generateStorageApi(data.data)
  1397. );
  1398. let $remark = popsPanelContentUtils.createSectionContainerItem_textarea(
  1399. remark_template
  1400. );
  1401. $fragment.append(
  1402. $enable,
  1403. $name,
  1404. $url,
  1405. $enableRegExpToMatchUrl,
  1406. $cookieName,
  1407. $enableRegExpToMatchCookieName,
  1408. $operationMode,
  1409. $remark
  1410. );
  1411. return $fragment;
  1412. },
  1413. onsubmit: ($form, isEdit, editData) => {
  1414. let $ulist_li = $form.querySelectorAll(
  1415. ".rule-form-ulist > li"
  1416. );
  1417. let data = this.getTemplateData();
  1418. if (isEdit) {
  1419. data.uuid = editData.uuid;
  1420. }
  1421. try {
  1422. $ulist_li.forEach(($li) => {
  1423. let formConfig = Reflect.get($li, "__formConfig__");
  1424. let attrs = Reflect.get(formConfig, "attributes");
  1425. let storageApi = Reflect.get($li, PROPS_STORAGE_API);
  1426. let key = Reflect.get(attrs, ATTRIBUTE_KEY);
  1427. let defaultValue = Reflect.get(attrs, ATTRIBUTE_DEFAULT_VALUE);
  1428. let value = storageApi.get(key, defaultValue);
  1429. if (Reflect.has(data, key)) {
  1430. Reflect.set(data, key, value);
  1431. } else if (Reflect.has(data.data, key)) {
  1432. Reflect.set(data.data, key, value);
  1433. } else {
  1434. log.error(`${key}不在数据中`);
  1435. }
  1436. });
  1437. if (data.name.trim() === "") {
  1438. Qmsg.error("规则名称不能为空");
  1439. return {
  1440. success: false,
  1441. data
  1442. };
  1443. }
  1444. if (data.data.url.trim() === "") {
  1445. Qmsg.error("网址不能为空");
  1446. return {
  1447. success: false,
  1448. data
  1449. };
  1450. }
  1451. if (data.data.cookieName.trim() === "") {
  1452. Qmsg.error("Cookie名称不能为空");
  1453. return {
  1454. success: false,
  1455. data
  1456. };
  1457. }
  1458. if (isEdit) {
  1459. return {
  1460. success: this.updateData(data),
  1461. data
  1462. };
  1463. } else {
  1464. return {
  1465. success: this.addData(data),
  1466. data
  1467. };
  1468. }
  1469. } catch (error) {
  1470. log.error(error);
  1471. return {
  1472. success: false,
  1473. data
  1474. };
  1475. } finally {
  1476. this.init();
  1477. }
  1478. },
  1479. style: (
  1480. /*css*/
  1481. `
  1482. .pops-panel-textarea textarea{
  1483. height: 150px;
  1484. }
  1485. .pops-panel-item-left-desc-text{
  1486. line-height: normal;
  1487. margin-top: 6px;
  1488. font-size: 0.8em;
  1489. color: rgb(108, 108, 108);
  1490. max-width: 100px;
  1491. }
  1492. `
  1493. )
  1494. },
  1495. delete: {
  1496. enable: true,
  1497. deleteCallBack: (data) => {
  1498. return this.deleteData(data);
  1499. }
  1500. }
  1501. }
  1502. });
  1503. ruleView.showView();
  1504. },
  1505. /**
  1506. * 获取模板数据
  1507. */
  1508. getTemplateData() {
  1509. return {
  1510. uuid: utils.generateUUID(),
  1511. enable: true,
  1512. name: "",
  1513. data: {
  1514. url: "",
  1515. enableRegExpToMatchUrl: false,
  1516. cookieName: "",
  1517. enableRegExpToMatchCookieName: false,
  1518. operationMode: "delete",
  1519. remark: ""
  1520. }
  1521. };
  1522. },
  1523. /**
  1524. * 获取数据
  1525. */
  1526. getData() {
  1527. return _GM_getValue(this.$key.STORAGE_KEY, []);
  1528. },
  1529. /**
  1530. * 设置数据
  1531. * @param data
  1532. */
  1533. setData(data) {
  1534. _GM_setValue(this.$key.STORAGE_KEY, data);
  1535. },
  1536. /**
  1537. * 添加数据
  1538. * @param data
  1539. */
  1540. addData(data) {
  1541. let localData = this.getData();
  1542. let findIndex = localData.findIndex((item) => item.uuid == data.uuid);
  1543. if (findIndex === -1) {
  1544. localData.push(data);
  1545. _GM_setValue(this.$key.STORAGE_KEY, localData);
  1546. return true;
  1547. } else {
  1548. return false;
  1549. }
  1550. },
  1551. /**
  1552. * 更新数据
  1553. * @param data
  1554. */
  1555. updateData(data) {
  1556. let localData = this.getData();
  1557. let index = localData.findIndex((item) => item.uuid == data.uuid);
  1558. let updateFlag = false;
  1559. if (index !== -1) {
  1560. updateFlag = true;
  1561. localData[index] = data;
  1562. }
  1563. this.setData(localData);
  1564. return updateFlag;
  1565. },
  1566. /**
  1567. * 删除数据
  1568. * @param data
  1569. */
  1570. deleteData(data) {
  1571. let localData = this.getData();
  1572. let index = localData.findIndex((item) => item.uuid == data.uuid);
  1573. let deleteFlag = false;
  1574. if (index !== -1) {
  1575. deleteFlag = true;
  1576. localData.splice(index, 1);
  1577. }
  1578. this.setData(localData);
  1579. return deleteFlag;
  1580. },
  1581. /**
  1582. * 清空数据
  1583. */
  1584. clearData() {
  1585. _GM_deleteValue(this.$key.STORAGE_KEY);
  1586. },
  1587. /**
  1588. * 导出规则
  1589. */
  1590. exportRule(fileName = "rule.json") {
  1591. let allRule = this.getData();
  1592. let blob = new Blob([JSON.stringify(allRule, null, 4)]);
  1593. let blobUrl = window.URL.createObjectURL(blob);
  1594. let $a = domUtils.createElement("a");
  1595. $a.href = blobUrl;
  1596. $a.download = fileName;
  1597. $a.click();
  1598. setTimeout(() => {
  1599. window.URL.revokeObjectURL(blobUrl);
  1600. }, 1500);
  1601. },
  1602. /**
  1603. * 导入规则
  1604. */
  1605. importRule() {
  1606. let $alert = __pops.alert({
  1607. title: {
  1608. text: "请选择导入方式",
  1609. position: "center"
  1610. },
  1611. content: {
  1612. text: (
  1613. /*html*/
  1614. `
  1615. <div class="import-mode" data-mode="local">本地导入</div>
  1616. <div class="import-mode" data-mode="network">网络导入</div>
  1617. `
  1618. ),
  1619. html: true
  1620. },
  1621. width: PanelUISize.info.width,
  1622. height: PanelUISize.info.height,
  1623. style: (
  1624. /*css*/
  1625. `
  1626. .import-mode{
  1627. display: inline-block;
  1628. margin: 10px;
  1629. padding: 10px;
  1630. border: 1px solid #ccc;
  1631. border-radius: 5px;
  1632. cursor: pointer;
  1633. }
  1634. `
  1635. )
  1636. });
  1637. let $local = $alert.$shadowRoot.querySelector(
  1638. ".import-mode[data-mode='local']"
  1639. );
  1640. let $network = $alert.$shadowRoot.querySelector(
  1641. ".import-mode[data-mode='network']"
  1642. );
  1643. domUtils.on($local, "click", (event) => {
  1644. utils.preventEvent(event);
  1645. $alert.close();
  1646. let $input = domUtils.createElement("input", {
  1647. type: "file",
  1648. accept: ".json"
  1649. });
  1650. domUtils.on($input, ["propertychange", "input"], (event2) => {
  1651. var _a2;
  1652. if (!((_a2 = $input.files) == null ? void 0 : _a2.length)) {
  1653. return;
  1654. }
  1655. let uploadFile = $input.files[0];
  1656. let fileReader = new FileReader();
  1657. fileReader.onload = () => {
  1658. let data = utils.toJSON(fileReader.result);
  1659. if (!Array.isArray(data)) {
  1660. log.error("不是正确的规则文件", data);
  1661. Qmsg.error("不是正确的规则文件");
  1662. return;
  1663. }
  1664. this.setData(data);
  1665. Qmsg.success(`成功导入 ${data.length}条规则`);
  1666. };
  1667. fileReader.readAsText(uploadFile, "UTF-8");
  1668. });
  1669. $input.click();
  1670. });
  1671. domUtils.on($network, "click", (event) => {
  1672. utils.preventEvent(event);
  1673. $alert.close();
  1674. __pops.prompt({
  1675. title: {
  1676. text: "网络导入",
  1677. position: "center"
  1678. },
  1679. content: {
  1680. text: "",
  1681. placeholder: "url",
  1682. focus: true
  1683. },
  1684. btn: {
  1685. ok: {
  1686. callback: async (eventDetails, event2) => {
  1687. let url = eventDetails.text;
  1688. if (utils.isNull(url)) {
  1689. Qmsg.error("请填入完整的url");
  1690. return;
  1691. }
  1692. let response = await httpx.get(url);
  1693. if (!response.status) {
  1694. return;
  1695. }
  1696. let data = utils.toJSON(response.data.responseText);
  1697. if (!Array.isArray(data)) {
  1698. log.error("不是正确的规则文件", response, data);
  1699. Qmsg.error("不是正确的规则文件");
  1700. return;
  1701. }
  1702. this.setData(data);
  1703. eventDetails.close();
  1704. Qmsg.success(`成功导入 ${data.length}条规则`);
  1705. }
  1706. }
  1707. },
  1708. width: PanelUISize.info.width,
  1709. height: "auto"
  1710. });
  1711. });
  1712. }
  1713. };
  1714. const Component_Rule = {
  1715. id: "view-rule",
  1716. title: "规则",
  1717. headerTitle: "Cookie操作规则",
  1718. forms: [
  1719. {
  1720. type: "forms",
  1721. text: "",
  1722. forms: [
  1723. UIButton(
  1724. "自定义规则",
  1725. "操作Cookie的规则",
  1726. "管理",
  1727. void 0,
  1728. false,
  1729. false,
  1730. "default",
  1731. () => {
  1732. CookieRule.showView();
  1733. }
  1734. )
  1735. ]
  1736. },
  1737. {
  1738. type: "forms",
  1739. text: "",
  1740. forms: [
  1741. UIButton(
  1742. "数据导入",
  1743. "导入自定义规则数据",
  1744. "导入",
  1745. void 0,
  1746. false,
  1747. false,
  1748. "primary",
  1749. () => {
  1750. CookieRule.importRule();
  1751. }
  1752. ),
  1753. UIButton(
  1754. "数据导出",
  1755. "导出自定义规则数据",
  1756. "导出",
  1757. void 0,
  1758. false,
  1759. false,
  1760. "primary",
  1761. () => {
  1762. CookieRule.exportRule("CookieManagerRule.json");
  1763. }
  1764. )
  1765. ]
  1766. }
  1767. ]
  1768. };
  1769. const PopsPanel = {
  1770. /** 数据 */
  1771. $data: {
  1772. __data: null,
  1773. __oneSuccessExecMenu: null,
  1774. __onceExec: null,
  1775. __listenData: null,
  1776. /**
  1777. * 菜单项的默认值
  1778. */
  1779. get data() {
  1780. if (PopsPanel.$data.__data == null) {
  1781. PopsPanel.$data.__data = new utils.Dictionary();
  1782. }
  1783. return PopsPanel.$data.__data;
  1784. },
  1785. /**
  1786. * 成功只执行了一次的项
  1787. */
  1788. get oneSuccessExecMenu() {
  1789. if (PopsPanel.$data.__oneSuccessExecMenu == null) {
  1790. PopsPanel.$data.__oneSuccessExecMenu = new utils.Dictionary();
  1791. }
  1792. return PopsPanel.$data.__oneSuccessExecMenu;
  1793. },
  1794. /**
  1795. * 成功只执行了一次的项
  1796. */
  1797. get onceExec() {
  1798. if (PopsPanel.$data.__onceExec == null) {
  1799. PopsPanel.$data.__onceExec = new utils.Dictionary();
  1800. }
  1801. return PopsPanel.$data.__onceExec;
  1802. },
  1803. /** 脚本名,一般用在设置的标题上 */
  1804. get scriptName() {
  1805. return SCRIPT_NAME;
  1806. },
  1807. /** 菜单项的总值在本地数据配置的键名 */
  1808. key: KEY,
  1809. /** 菜单项在attributes上配置的菜单键 */
  1810. attributeKeyName: ATTRIBUTE_KEY,
  1811. /** 菜单项在attributes上配置的菜单默认值 */
  1812. attributeDefaultValueName: ATTRIBUTE_DEFAULT_VALUE
  1813. },
  1814. /** 监听器 */
  1815. $listener: {
  1816. /**
  1817. * 值改变的监听器
  1818. */
  1819. get listenData() {
  1820. if (PopsPanel.$data.__listenData == null) {
  1821. PopsPanel.$data.__listenData = new utils.Dictionary();
  1822. }
  1823. return PopsPanel.$data.__listenData;
  1824. }
  1825. },
  1826. init() {
  1827. let contentConfigList = this.getPanelContentConfig();
  1828. this.initPanelConfigDefaultValue([...contentConfigList]);
  1829. this.registerMenu();
  1830. },
  1831. /** 判断是否是顶层窗口 */
  1832. isTopWindow() {
  1833. return _unsafeWindow.top === _unsafeWindow.self;
  1834. },
  1835. /** 初始化进行注册(不可用)油猴菜单 */
  1836. registerMenu() {
  1837. if (!this.isTopWindow()) {
  1838. return;
  1839. }
  1840. GM_Menu.add([
  1841. {
  1842. key: "show_pops_panel_setting",
  1843. text: "⚙ 设置",
  1844. autoReload: false,
  1845. isStoreValue: false,
  1846. showText(text) {
  1847. return text;
  1848. },
  1849. callback: () => {
  1850. this.showPanel();
  1851. }
  1852. }
  1853. ]);
  1854. },
  1855. /** 初始化菜单项的默认值保存到本地数据中 */
  1856. initPanelConfigDefaultValue(contentConfigList) {
  1857. let that = this;
  1858. function initDefaultValue(config) {
  1859. if (!config.attributes) {
  1860. return;
  1861. }
  1862. let needInitConfig = {};
  1863. let key = config.attributes[ATTRIBUTE_KEY];
  1864. if (key != null) {
  1865. needInitConfig[key] = config.attributes[ATTRIBUTE_DEFAULT_VALUE];
  1866. }
  1867. let __attr_init__ = config.attributes[ATTRIBUTE_INIT];
  1868. if (typeof __attr_init__ === "function") {
  1869. let __attr_result__ = __attr_init__();
  1870. if (typeof __attr_result__ === "boolean" && !__attr_result__) {
  1871. return;
  1872. }
  1873. }
  1874. let initMoreValue = config.attributes[ATTRIBUTE_INIT_MORE_VALUE];
  1875. if (initMoreValue && typeof initMoreValue === "object") {
  1876. Object.assign(needInitConfig, initMoreValue);
  1877. }
  1878. let needInitConfigList = Object.keys(needInitConfig);
  1879. if (!needInitConfigList.length) {
  1880. if (config.type !== "button") {
  1881. log.warn("请先配置键", config);
  1882. }
  1883. return;
  1884. }
  1885. needInitConfigList.forEach((__key) => {
  1886. let __defaultValue = needInitConfig[__key];
  1887. if (that.$data.data.has(__key)) {
  1888. log.warn("请检查该key(已存在): " + __key);
  1889. }
  1890. that.$data.data.set(__key, __defaultValue);
  1891. });
  1892. }
  1893. function loopInitDefaultValue(configList) {
  1894. for (let index = 0; index < configList.length; index++) {
  1895. let configItem = configList[index];
  1896. initDefaultValue(configItem);
  1897. let childForms = configItem.forms;
  1898. if (childForms && Array.isArray(childForms)) {
  1899. loopInitDefaultValue(childForms);
  1900. }
  1901. }
  1902. }
  1903. for (let index = 0; index < contentConfigList.length; index++) {
  1904. let leftContentConfigItem = contentConfigList[index];
  1905. if (!leftContentConfigItem.forms) {
  1906. continue;
  1907. }
  1908. let rightContentConfigList = leftContentConfigItem.forms;
  1909. if (rightContentConfigList && Array.isArray(rightContentConfigList)) {
  1910. loopInitDefaultValue(rightContentConfigList);
  1911. }
  1912. }
  1913. },
  1914. /**
  1915. * 设置值
  1916. * @param key 键
  1917. * @param value 值
  1918. */
  1919. setValue(key, value) {
  1920. let locaData = _GM_getValue(KEY, {});
  1921. let oldValue = locaData[key];
  1922. locaData[key] = value;
  1923. _GM_setValue(KEY, locaData);
  1924. if (this.$listener.listenData.has(key)) {
  1925. this.$listener.listenData.get(key).callback(key, oldValue, value);
  1926. }
  1927. },
  1928. /**
  1929. * 获取值
  1930. * @param key 键
  1931. * @param defaultValue 默认值
  1932. */
  1933. getValue(key, defaultValue) {
  1934. let locaData = _GM_getValue(KEY, {});
  1935. let localValue = locaData[key];
  1936. if (localValue == null) {
  1937. if (this.$data.data.has(key)) {
  1938. return this.$data.data.get(key);
  1939. }
  1940. return defaultValue;
  1941. }
  1942. return localValue;
  1943. },
  1944. /**
  1945. * 删除值
  1946. * @param key 键
  1947. */
  1948. deleteValue(key) {
  1949. let locaData = _GM_getValue(KEY, {});
  1950. let oldValue = locaData[key];
  1951. Reflect.deleteProperty(locaData, key);
  1952. _GM_setValue(KEY, locaData);
  1953. if (this.$listener.listenData.has(key)) {
  1954. this.$listener.listenData.get(key).callback(key, oldValue, void 0);
  1955. }
  1956. },
  1957. /**
  1958. * 监听调用setValue、deleteValue
  1959. * @param key 需要监听的键
  1960. * @param callback
  1961. */
  1962. addValueChangeListener(key, callback, option) {
  1963. let listenerId = Math.random();
  1964. this.$listener.listenData.set(key, {
  1965. id: listenerId,
  1966. key,
  1967. callback
  1968. });
  1969. if (option) {
  1970. if (option.immediate) {
  1971. callback(key, this.getValue(key), this.getValue(key));
  1972. }
  1973. }
  1974. return listenerId;
  1975. },
  1976. /**
  1977. * 移除监听
  1978. * @param listenerId 监听的id
  1979. */
  1980. removeValueChangeListener(listenerId) {
  1981. let deleteKey = null;
  1982. for (const [key, value] of this.$listener.listenData.entries()) {
  1983. if (value.id === listenerId) {
  1984. deleteKey = key;
  1985. break;
  1986. }
  1987. }
  1988. if (typeof deleteKey === "string") {
  1989. this.$listener.listenData.delete(deleteKey);
  1990. } else {
  1991. console.warn("没有找到对应的监听器");
  1992. }
  1993. },
  1994. /**
  1995. * 主动触发菜单值改变的回调
  1996. * @param key 菜单键
  1997. * @param newValue 想要触发的新值,默认使用当前值
  1998. * @param oldValue 想要触发的旧值,默认使用当前值
  1999. */
  2000. triggerMenuValueChange(key, newValue, oldValue) {
  2001. if (this.$listener.listenData.has(key)) {
  2002. let listenData = this.$listener.listenData.get(key);
  2003. if (typeof listenData.callback === "function") {
  2004. let value = this.getValue(key);
  2005. let __newValue = value;
  2006. let __oldValue = value;
  2007. if (typeof newValue !== "undefined" && arguments.length > 1) {
  2008. __newValue = newValue;
  2009. }
  2010. if (typeof oldValue !== "undefined" && arguments.length > 2) {
  2011. __oldValue = oldValue;
  2012. }
  2013. listenData.callback(key, __oldValue, __newValue);
  2014. }
  2015. }
  2016. },
  2017. /**
  2018. * 判断该键是否存在
  2019. * @param key 键
  2020. */
  2021. hasKey(key) {
  2022. let locaData = _GM_getValue(KEY, {});
  2023. return key in locaData;
  2024. },
  2025. /**
  2026. * 自动判断菜单是否启用,然后执行回调
  2027. * @param key
  2028. * @param callback 回调
  2029. * @param isReverse 逆反判断菜单启用
  2030. * @param checkEnableCallBack 自定义检测菜单的值,可自行决定是否强制启用菜单,true是启用菜单,false是不启用菜单
  2031. */
  2032. execMenu(key, callback, isReverse = false, checkEnableCallBack) {
  2033. if (!(typeof key === "string" || typeof key === "object" && Array.isArray(key))) {
  2034. throw new TypeError("key 必须是字符串或者字符串数组");
  2035. }
  2036. let runKeyList = [];
  2037. if (typeof key === "object" && Array.isArray(key)) {
  2038. runKeyList = [...key];
  2039. } else {
  2040. runKeyList.push(key);
  2041. }
  2042. let value = void 0;
  2043. for (let index = 0; index < runKeyList.length; index++) {
  2044. const runKey = runKeyList[index];
  2045. if (!this.$data.data.has(runKey)) {
  2046. log.warn(`${key} 键不存在`);
  2047. return;
  2048. }
  2049. let runValue = PopsPanel.getValue(runKey);
  2050. if (isReverse) {
  2051. runValue = !runValue;
  2052. }
  2053. if (typeof checkEnableCallBack === "function") {
  2054. let checkResult = checkEnableCallBack(runKey, runValue);
  2055. if (typeof checkResult === "boolean") {
  2056. runValue = checkResult;
  2057. }
  2058. }
  2059. if (!runValue) {
  2060. break;
  2061. }
  2062. value = runValue;
  2063. }
  2064. if (value) {
  2065. callback(value);
  2066. }
  2067. },
  2068. /**
  2069. * 自动判断菜单是否启用,然后执行回调,只会执行一次
  2070. * @param key
  2071. * @param callback 回调
  2072. * @param getValueFn 自定义处理获取当前值,值true是启用并执行回调,值false是不执行回调
  2073. * @param handleValueChangeFn 自定义处理值改变时的回调,值true是启用并执行回调,值false是不执行回调
  2074. * @param checkEnableCallBack 自定义检测菜单的值,可自行决定是否强制启用菜单,true是启用菜单,false是不启用菜单
  2075. */
  2076. execMenuOnce(key, callback, getValueFn, handleValueChangeFn, checkEnableCallBack) {
  2077. if (typeof key !== "string") {
  2078. throw new TypeError("key 必须是字符串");
  2079. }
  2080. if (!this.$data.data.has(key)) {
  2081. log.warn(`${key} 键不存在`);
  2082. return;
  2083. }
  2084. if (this.$data.oneSuccessExecMenu.has(key)) {
  2085. return;
  2086. }
  2087. this.$data.oneSuccessExecMenu.set(key, 1);
  2088. let __getValue = () => {
  2089. let localValue = PopsPanel.getValue(key);
  2090. return typeof getValueFn === "function" ? getValueFn(key, localValue) : localValue;
  2091. };
  2092. let resultStyleList = [];
  2093. let dynamicPushStyleNode = ($style) => {
  2094. let __value = __getValue();
  2095. let dynamicResultList = [];
  2096. if ($style instanceof HTMLStyleElement) {
  2097. dynamicResultList = [$style];
  2098. } else if (Array.isArray($style)) {
  2099. dynamicResultList = [
  2100. ...$style.filter(
  2101. (item) => item != null && item instanceof HTMLStyleElement
  2102. )
  2103. ];
  2104. }
  2105. if (__value) {
  2106. resultStyleList = resultStyleList.concat(dynamicResultList);
  2107. } else {
  2108. for (let index = 0; index < dynamicResultList.length; index++) {
  2109. let $css = dynamicResultList[index];
  2110. $css.remove();
  2111. dynamicResultList.splice(index, 1);
  2112. index--;
  2113. }
  2114. }
  2115. };
  2116. let checkMenuEnableCallBack = (currentValue) => {
  2117. return typeof checkEnableCallBack === "function" ? checkEnableCallBack(key, currentValue) : currentValue;
  2118. };
  2119. let changeCallBack = (currentValue) => {
  2120. let resultList = [];
  2121. if (checkMenuEnableCallBack(currentValue)) {
  2122. let result = callback(currentValue, dynamicPushStyleNode);
  2123. if (result instanceof HTMLStyleElement) {
  2124. resultList = [result];
  2125. } else if (Array.isArray(result)) {
  2126. resultList = [
  2127. ...result.filter(
  2128. (item) => item != null && item instanceof HTMLStyleElement
  2129. )
  2130. ];
  2131. }
  2132. }
  2133. for (let index = 0; index < resultStyleList.length; index++) {
  2134. let $css = resultStyleList[index];
  2135. $css.remove();
  2136. resultStyleList.splice(index, 1);
  2137. index--;
  2138. }
  2139. resultStyleList = [...resultList];
  2140. };
  2141. this.addValueChangeListener(
  2142. key,
  2143. (__key, oldValue, newValue) => {
  2144. let __newValue = newValue;
  2145. if (typeof handleValueChangeFn === "function") {
  2146. __newValue = handleValueChangeFn(__key, newValue, oldValue);
  2147. }
  2148. changeCallBack(__newValue);
  2149. }
  2150. );
  2151. let value = __getValue();
  2152. if (value) {
  2153. changeCallBack(value);
  2154. }
  2155. },
  2156. /**
  2157. * 父子菜单联动,自动判断菜单是否启用,然后执行回调,只会执行一次
  2158. * @param key 菜单键
  2159. * @param childKey 子菜单键
  2160. * @param callback 回调
  2161. * @param replaceValueFn 用于修改mainValue,返回undefined则不做处理
  2162. */
  2163. execInheritMenuOnce(key, childKey, callback, replaceValueFn) {
  2164. let that = this;
  2165. const handleInheritValue = (key2, childKey2) => {
  2166. let mainValue = that.getValue(key2);
  2167. let childValue = that.getValue(childKey2);
  2168. if (typeof replaceValueFn === "function") {
  2169. let changedMainValue = replaceValueFn(mainValue, childValue);
  2170. if (changedMainValue != null) {
  2171. return changedMainValue;
  2172. }
  2173. }
  2174. return mainValue;
  2175. };
  2176. this.execMenuOnce(
  2177. key,
  2178. callback,
  2179. () => {
  2180. return handleInheritValue(key, childKey);
  2181. },
  2182. () => {
  2183. return handleInheritValue(key, childKey);
  2184. }
  2185. );
  2186. this.execMenuOnce(
  2187. childKey,
  2188. () => {
  2189. },
  2190. () => false,
  2191. () => {
  2192. this.triggerMenuValueChange(key);
  2193. return false;
  2194. }
  2195. );
  2196. },
  2197. /**
  2198. * 根据自定义key只执行一次
  2199. * @param key 自定义key
  2200. */
  2201. onceExec(key, callback) {
  2202. if (typeof key !== "string") {
  2203. throw new TypeError("key 必须是字符串");
  2204. }
  2205. if (this.$data.onceExec.has(key)) {
  2206. return;
  2207. }
  2208. callback();
  2209. this.$data.onceExec.set(key, 1);
  2210. },
  2211. /**
  2212. * 显示设置面板
  2213. */
  2214. showPanel() {
  2215. __pops.panel({
  2216. title: {
  2217. text: `${SCRIPT_NAME}-设置`,
  2218. position: "center",
  2219. html: false,
  2220. style: ""
  2221. },
  2222. content: this.getPanelContentConfig(),
  2223. mask: {
  2224. enable: true,
  2225. clickEvent: {
  2226. toClose: true,
  2227. toHide: false
  2228. }
  2229. },
  2230. zIndex() {
  2231. let maxZIndex = Utils.getMaxZIndex();
  2232. let popsMaxZIndex = __pops.config.InstanceUtils.getPopsMaxZIndex().zIndex;
  2233. return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100;
  2234. },
  2235. width: PanelUISize.setting.width,
  2236. height: PanelUISize.setting.height,
  2237. drag: true,
  2238. only: true
  2239. });
  2240. },
  2241. /**
  2242. * 获取配置内容
  2243. */
  2244. getPanelContentConfig() {
  2245. let configList = [
  2246. Component_Common,
  2247. Component_Rule
  2248. ];
  2249. return configList;
  2250. }
  2251. };
  2252. const CookieManager = {
  2253. get cookieManagerApiName() {
  2254. let managerApi = PopsPanel.getValue(
  2255. "cookie-manager-api",
  2256. "document.cookie"
  2257. );
  2258. return managerApi;
  2259. },
  2260. get cookieManager() {
  2261. if (this.cookieManagerApiName === "GM_cookie") {
  2262. return _GM_cookie;
  2263. } else if (this.cookieManagerApiName === "cookieStore") {
  2264. let cookieStore = _unsafeWindow.cookieStore;
  2265. return {
  2266. list(options, callback) {
  2267. cookieStore.getAll().then((result) => {
  2268. callback(result);
  2269. }).catch((reason) => {
  2270. log.error(reason);
  2271. Qmsg.error(reason.toString());
  2272. });
  2273. },
  2274. set(cookieInfo, callback) {
  2275. cookieStore.set(cookieInfo).then(() => {
  2276. callback();
  2277. }).catch((reason) => {
  2278. callback(reason);
  2279. });
  2280. },
  2281. delete(cookieInfo, callback) {
  2282. cookieStore.delete(cookieInfo).then((result) => {
  2283. callback();
  2284. }).catch((reason) => {
  2285. callback(reason);
  2286. });
  2287. }
  2288. };
  2289. } else {
  2290. return utilsCookieManager;
  2291. }
  2292. },
  2293. /**
  2294. * 查询所有Cookie
  2295. */
  2296. queryAllCookie() {
  2297. return new Promise(
  2298. (resolve, reject) => {
  2299. try {
  2300. this.cookieManager.list({}, (cookieListResult) => {
  2301. let __cookieListResult__ = cookieListResult || [];
  2302. __cookieListResult__ = __cookieListResult__.sort(
  2303. (a, b) => a.name.localeCompare(b.name)
  2304. );
  2305. resolve(__cookieListResult__);
  2306. });
  2307. } catch (error) {
  2308. log.error(error);
  2309. Qmsg.error(error.toString());
  2310. reject(error);
  2311. }
  2312. }
  2313. );
  2314. },
  2315. /**
  2316. * 清除所有Cookie
  2317. */
  2318. deleteAllCookie() {
  2319. return new Promise((resolve, reject) => {
  2320. try {
  2321. this.cookieManager.list({}, async (cookieListResult) => {
  2322. const __cookieListResult__ = cookieListResult || [];
  2323. const result = {
  2324. success: 0,
  2325. error: 0
  2326. };
  2327. for (let index = 0; index < __cookieListResult__.length; index++) {
  2328. const cookieListItem = __cookieListResult__[index];
  2329. let deleteError = await new Promise((deleteResolve) => {
  2330. this.deleteCookie(cookieListItem).then((deleteResult) => {
  2331. deleteResolve(deleteResult);
  2332. });
  2333. });
  2334. if (deleteError) {
  2335. result.error++;
  2336. } else {
  2337. result.success++;
  2338. }
  2339. }
  2340. resolve(result);
  2341. });
  2342. } catch (error) {
  2343. log.error(error);
  2344. Qmsg.error(error.toString());
  2345. reject(error);
  2346. }
  2347. });
  2348. },
  2349. /**
  2350. * 添加Cookie
  2351. */
  2352. addCookie(cookieInfo) {
  2353. return new Promise((resolve, reject) => {
  2354. try {
  2355. delete cookieInfo.hostOnly;
  2356. CookieManager.cookieManager.set(cookieInfo, (error) => {
  2357. log.info(["添加Cookie:" + cookieInfo.name, cookieInfo]);
  2358. resolve(error);
  2359. });
  2360. } catch (error) {
  2361. log.error(error);
  2362. Qmsg.error(error.toString());
  2363. reject(error);
  2364. }
  2365. });
  2366. },
  2367. /**
  2368. * 删除Cookie
  2369. */
  2370. deleteCookie(cookieInfo) {
  2371. return new Promise((resolve, reject) => {
  2372. try {
  2373. CookieManager.cookieManager.delete(cookieInfo, (error) => {
  2374. log.info(["删除Cookie:" + cookieInfo.name, cookieInfo]);
  2375. resolve(error);
  2376. });
  2377. } catch (error) {
  2378. log.error(error);
  2379. Qmsg.error(error.toString());
  2380. reject(error);
  2381. }
  2382. });
  2383. },
  2384. /**
  2385. * 更新Cookie
  2386. */
  2387. updateCookie(cookieInfo) {
  2388. return new Promise(
  2389. async (resolve, reject) => {
  2390. let result;
  2391. try {
  2392. let deleteError = await CookieManager.deleteCookie(cookieInfo);
  2393. if (deleteError) {
  2394. throw new TypeError(deleteError.toString());
  2395. }
  2396. let addError = await CookieManager.addCookie(cookieInfo);
  2397. if (addError) {
  2398. throw new TypeError(addError.toString());
  2399. }
  2400. } catch (error) {
  2401. result = error;
  2402. } finally {
  2403. log.info(["更新Cookie:" + cookieInfo.name, cookieInfo]);
  2404. resolve(result);
  2405. }
  2406. }
  2407. );
  2408. }
  2409. };
  2410. let edit_ui_input = (text, getValue, setValue, disabled) => {
  2411. let config = {
  2412. text,
  2413. type: "input",
  2414. isNumber: false,
  2415. isPassword: false,
  2416. props: {},
  2417. attributes: {},
  2418. description: "",
  2419. getValue() {
  2420. return getValue();
  2421. },
  2422. callback(event, value) {
  2423. setValue(value);
  2424. },
  2425. placeholder: "",
  2426. disabled: Boolean(disabled)
  2427. };
  2428. return config;
  2429. };
  2430. let edit_ui_select = (text, data, getValue, setValue, disabled) => {
  2431. let config = {
  2432. text,
  2433. type: "select",
  2434. description: "",
  2435. attributes: {},
  2436. props: {},
  2437. getValue() {
  2438. return getValue();
  2439. },
  2440. callback(event, isSelectedValue, isSelectedText) {
  2441. let value = isSelectedValue;
  2442. setValue(value);
  2443. },
  2444. // @ts-ignore
  2445. data,
  2446. disabled: Boolean(disabled)
  2447. };
  2448. return config;
  2449. };
  2450. const CookieManagerEditView = {
  2451. init() {
  2452. },
  2453. /**
  2454. * 显示视图
  2455. * @param cookieInfo 需要编辑的cookie
  2456. * @param dialogCloseCallBack 弹窗关闭的回调
  2457. */
  2458. showView(__cookieInfo__, dialogCloseCallBack) {
  2459. let isEdit = !!__cookieInfo__;
  2460. let cookieInfo = utils.assign(
  2461. {
  2462. name: "",
  2463. value: "",
  2464. domain: window.location.hostname,
  2465. path: "/",
  2466. secure: false,
  2467. hostOnly: false,
  2468. httpOnly: false,
  2469. sameSite: "lax",
  2470. expirationDate: Date.now() + 60 * 60 * 24 * 30 * 1e3
  2471. },
  2472. __cookieInfo__,
  2473. true
  2474. );
  2475. if (CookieManager.cookieManagerApiName === "cookieStore") {
  2476. if (cookieInfo.expires) {
  2477. cookieInfo.expirationDate = cookieInfo.expires;
  2478. }
  2479. }
  2480. let $dialog = __pops.confirm({
  2481. title: {
  2482. text: isEdit ? "编辑Cookie" : "添加Cookie",
  2483. position: "center"
  2484. },
  2485. content: {
  2486. text: "",
  2487. html: true
  2488. },
  2489. drag: true,
  2490. btn: {
  2491. position: "center",
  2492. ok: {
  2493. text: isEdit ? "编辑" : "添加",
  2494. async callback(eventDetails, event) {
  2495. let valid = CookieManagerEditView.validCookieInfo(cookieInfo);
  2496. if (!valid) {
  2497. return;
  2498. }
  2499. cookieInfo.value = encodeURIComponent(cookieInfo.value);
  2500. if (CookieManager.cookieManagerApiName === "document.cookie") {
  2501. cookieInfo.domain = "";
  2502. } else if (CookieManager.cookieManagerApiName === "GM_cookie") {
  2503. cookieInfo.expirationDate = Math.floor(
  2504. cookieInfo.expirationDate / 1e3
  2505. );
  2506. }
  2507. if (isEdit) {
  2508. let result = await CookieManager.updateCookie(cookieInfo);
  2509. if (result) {
  2510. Qmsg.error(result.toString());
  2511. } else {
  2512. Qmsg.success("修改成功");
  2513. eventDetails.close();
  2514. }
  2515. } else {
  2516. let result = await CookieManager.addCookie(cookieInfo);
  2517. if (result) {
  2518. Qmsg.error(result.toString());
  2519. } else {
  2520. Qmsg.success("添加成功");
  2521. eventDetails.close();
  2522. }
  2523. }
  2524. if (typeof dialogCloseCallBack === "function") {
  2525. dialogCloseCallBack(cookieInfo);
  2526. }
  2527. }
  2528. },
  2529. cancel: {
  2530. text: "取消"
  2531. }
  2532. },
  2533. mask: {
  2534. enable: true
  2535. },
  2536. width: window.innerWidth > 350 ? "350px" : "80vw",
  2537. height: PanelUISize.setting.height,
  2538. style: (
  2539. /*css*/
  2540. `
  2541. ${__pops.config.cssText.panelCSS}
  2542.  
  2543. .pops-panel-input input:disabled{
  2544. color: #b4b4b4;
  2545. }
  2546. .pops-confirm-content{
  2547. padding: 10px;
  2548. }
  2549. .pops-confirm-content li{
  2550. display: flex;
  2551. flex-direction: column;
  2552. }
  2553. .pops-panel-item-left-text{
  2554. margin-bottom: 5px;
  2555. }
  2556. .pops-panel-input.pops-input-disabled{
  2557. border: 1px solid #dcdfe6;
  2558. }
  2559. #cookie-item-property-expires{
  2560. border: 1px solid rgb(184, 184, 184, var(--pops-bd-opacity));
  2561. border-radius: 4px;
  2562. background-color: #ffffff;
  2563. width: 100%;
  2564. height: 32px;
  2565. padding: 0px 8px;
  2566. }
  2567. #cookie-item-property-expires:hover{
  2568. box-shadow: 0 0 0 1px #c0c4cc inset;
  2569. }
  2570. #cookie-item-property-expires:focus,
  2571. #cookie-item-property-expires:focus-within{
  2572. outline: 0;
  2573. border: 1px solid #409eff;
  2574. border-radius: 4px;
  2575. box-shadow: none;
  2576. }
  2577. `
  2578. )
  2579. });
  2580. let $editContent = $dialog.$shadowRoot.querySelector(
  2581. ".pops-confirm-content"
  2582. );
  2583. let panelHandleContentUtils = __pops.config.panelHandleContentUtils();
  2584. let $name = panelHandleContentUtils.createSectionContainerItem_input(
  2585. edit_ui_input(
  2586. "name",
  2587. () => cookieInfo.name,
  2588. (value) => cookieInfo.name = value,
  2589. isEdit
  2590. )
  2591. );
  2592. let $value = panelHandleContentUtils.createSectionContainerItem_input(
  2593. edit_ui_input(
  2594. "value",
  2595. () => cookieInfo.value,
  2596. (value) => cookieInfo.value = value
  2597. )
  2598. );
  2599. let $domain = panelHandleContentUtils.createSectionContainerItem_input(
  2600. edit_ui_input(
  2601. "domain",
  2602. () => cookieInfo.domain,
  2603. (value) => cookieInfo.domain = value
  2604. )
  2605. );
  2606. let $path = panelHandleContentUtils.createSectionContainerItem_input(
  2607. edit_ui_input(
  2608. "path",
  2609. () => cookieInfo.path,
  2610. (value) => cookieInfo.path = value
  2611. )
  2612. );
  2613. let $expires;
  2614. if (cookieInfo.session) {
  2615. $expires = panelHandleContentUtils.createSectionContainerItem_input(
  2616. edit_ui_input(
  2617. "expires",
  2618. () => "会话",
  2619. (value) => {
  2620. },
  2621. true
  2622. )
  2623. );
  2624. } else {
  2625. $expires = panelHandleContentUtils.createSectionContainerItem_own({
  2626. type: "own",
  2627. getLiElementCallBack: function(liElement) {
  2628. let $li = domUtils.createElement("li", {
  2629. innerHTML: (
  2630. /*html*/
  2631. `
  2632. <div class="pops-panel-item-left-text">
  2633. <p class="pops-panel-item-left-main-text">expires</p>
  2634. </div>
  2635. <div class="pops-panel-item-right-wrapper">
  2636. <input type="datetime-local" id="cookie-item-property-expires">
  2637. </div>
  2638. `
  2639. )
  2640. });
  2641. let $dateTime = $li.querySelector(
  2642. "#cookie-item-property-expires"
  2643. );
  2644. $dateTime.valueAsNumber = cookieInfo.expirationDate;
  2645. domUtils.on(
  2646. $dateTime,
  2647. ["change", "input", "propertychange"],
  2648. (event) => {
  2649. utils.preventEvent(event);
  2650. cookieInfo.expirationDate = $dateTime.valueAsNumber;
  2651. }
  2652. );
  2653. return $li;
  2654. }
  2655. });
  2656. }
  2657. let $httpOnly = panelHandleContentUtils.createSectionContainerItem_select(
  2658. edit_ui_select(
  2659. "httpOnly",
  2660. [
  2661. {
  2662. text: "true",
  2663. value: true
  2664. },
  2665. {
  2666. text: "false",
  2667. value: false
  2668. }
  2669. ],
  2670. () => cookieInfo.httpOnly,
  2671. (value) => cookieInfo.httpOnly = value
  2672. )
  2673. );
  2674. let $secure = panelHandleContentUtils.createSectionContainerItem_select(
  2675. edit_ui_select(
  2676. "secure",
  2677. [
  2678. {
  2679. text: "true",
  2680. value: true
  2681. },
  2682. {
  2683. text: "false",
  2684. value: false
  2685. }
  2686. ],
  2687. () => cookieInfo.secure,
  2688. (value) => cookieInfo.secure = value
  2689. )
  2690. );
  2691. let sameSiteData = [
  2692. {
  2693. text: "no_restriction",
  2694. value: "no_restriction"
  2695. },
  2696. {
  2697. text: "lax",
  2698. value: "lax"
  2699. },
  2700. {
  2701. text: "strict",
  2702. value: "strict"
  2703. },
  2704. {
  2705. text: "unspecified",
  2706. value: "unspecified"
  2707. }
  2708. ];
  2709. if (CookieManager.cookieManagerApiName === "cookieStore") {
  2710. sameSiteData = [
  2711. {
  2712. text: "lax",
  2713. value: "lax"
  2714. },
  2715. {
  2716. text: "strict",
  2717. value: "strict"
  2718. },
  2719. {
  2720. text: "none",
  2721. value: "none"
  2722. }
  2723. ];
  2724. }
  2725. let $sameSite = panelHandleContentUtils.createSectionContainerItem_select(
  2726. edit_ui_select(
  2727. "sameSite",
  2728. sameSiteData,
  2729. () => cookieInfo.sameSite,
  2730. (value) => cookieInfo.sameSite = value
  2731. )
  2732. );
  2733. domUtils.append($editContent, [$name, $value]);
  2734. if (CookieManager.cookieManagerApiName === "GM_cookie") {
  2735. domUtils.append($editContent, [
  2736. $domain,
  2737. $path,
  2738. $expires,
  2739. $httpOnly,
  2740. $secure,
  2741. $sameSite
  2742. ]);
  2743. } else if (CookieManager.cookieManagerApiName === "cookieStore") {
  2744. domUtils.append($editContent, [$domain, $path, $expires, $sameSite]);
  2745. }
  2746. },
  2747. /**
  2748. * Cookie信息校验
  2749. */
  2750. validCookieInfo(cookieInfo) {
  2751. if (cookieInfo.name == null || cookieInfo.name == "") {
  2752. Qmsg.error("name不能为空");
  2753. return false;
  2754. }
  2755. if (cookieInfo.domain == null || cookieInfo.domain == "") {
  2756. Qmsg.error("domain不能为空");
  2757. return false;
  2758. }
  2759. if (cookieInfo.path == null || cookieInfo.path == "") {
  2760. Qmsg.error("path不能为空");
  2761. return false;
  2762. }
  2763. return true;
  2764. }
  2765. };
  2766. const CookieManagerView = {
  2767. init() {
  2768. this.registerMenu();
  2769. },
  2770. /**
  2771. * 显示视图
  2772. */
  2773. async showView() {
  2774. const $alert = __pops.alert({
  2775. title: {
  2776. text: "Cookie编辑器",
  2777. html: false,
  2778. position: "center"
  2779. },
  2780. content: {
  2781. text: (
  2782. /*html*/
  2783. `
  2784. <div class="cookie-wrapper">
  2785. <div class="cookie-search-wrapper">
  2786. <div class="cookie-search-inner">
  2787. <input type="text" placeholder="搜索Cookie名称">
  2788. </div>
  2789. <div class="cookie-search-setting">
  2790. <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">
  2791. <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>
  2792. </svg>
  2793. </div>
  2794. </div>
  2795. <div class="cookie-control-wrapper">
  2796. <button class="cookie-control-refresh" type="default">刷新</button>
  2797. <button class="cookie-control-add" type="default">添加</button>
  2798. <button class="cookie-control-copy-all" type="default">复制全部</button>
  2799. <button class="cookie-control-clear-all" type="default">清除全部</button>
  2800. <button class="cookie-control-rule-manager" type="default">规则管理</button>
  2801. <div class="cookie-setting">
  2802. <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">
  2803. <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>
  2804. </svg>
  2805. </div>
  2806. </div>
  2807. <div class="cookie-list-wrapper">
  2808. </div>
  2809. </div>
  2810. `
  2811. ),
  2812. html: true
  2813. },
  2814. btn: {
  2815. ok: {
  2816. enable: false
  2817. }
  2818. },
  2819. mask: {
  2820. enable: true
  2821. },
  2822. drag: true,
  2823. width: PanelUISize.setting.width,
  2824. height: PanelUISize.setting.height,
  2825. style: (
  2826. /*css*/
  2827. `
  2828. ${__pops.config.cssText.panelCSS}
  2829. .cookie-wrapper{
  2830. display: flex;
  2831. flex-direction: column;
  2832. padding: 10px;
  2833. gap: 10px;
  2834. }
  2835. .cookie-control-wrapper{
  2836. display: flex;
  2837. flex-wrap: wrap;
  2838. padding: 0px 10px;
  2839. gap: 5px;
  2840. --button-margin-left: 0px;
  2841. }
  2842. .cookie-search-wrapper{
  2843. display: flex;
  2844. align-items: center;
  2845. }
  2846. .cookie-search-inner{
  2847. width: 100%;
  2848. padding: 0px 10px;
  2849. }
  2850. .cookie-search-inner input{
  2851. height: 30px;
  2852. padding: 5px;
  2853. width: 100%;
  2854. }
  2855. .cookie-search-inner input:focus-visible{
  2856. outline: none;
  2857. }
  2858. .cookie-setting,
  2859. .cookie-search-setting{
  2860. display: flex;
  2861. align-items: center;
  2862. }
  2863. .cookie-setting svg,
  2864. .cookie-search-setting svg{
  2865. cursor: pointer;
  2866. }
  2867. .cookie-list-wrapper{
  2868. display: flex;
  2869. flex-wrap: wrap;
  2870. gap: 10px;
  2871. }
  2872. .cookie-item{
  2873. display: flex;
  2874. flex-direction: column;
  2875. padding: 10px 10px;
  2876. margin: 0px 10px;
  2877. background: #f1efef;
  2878. border-radius: 10px;
  2879. gap: 5px;
  2880. box-sizing: border-box;
  2881. width: 100%;
  2882. }
  2883. .cookie-item-group{
  2884. display: flex;
  2885. align-items: center;
  2886. }
  2887. .cookie-item-group-left{
  2888. width: 100px;
  2889. min-width: 100px;
  2890. max-width: 100px;
  2891. text-transform: capitalize
  2892. }
  2893. .cookie-item-group-control .cookie-item-group-right{
  2894. display: flex;
  2895. align-items: center;
  2896. gap: 10px;
  2897. }
  2898. .cookie-item-group-control .cookie-item-group-control-copy,
  2899. .cookie-item-group-control .cookie-item-group-control-edit,
  2900. .cookie-item-group-control .cookie-item-group-control-delete{
  2901. display: flex;
  2902. align-items: center;
  2903. }
  2904. .cookie-item-group-control .cookie-item-group-control-delete svg{
  2905. width: 16px;
  2906. height: 16px;
  2907. }
  2908. .cookie-item-group-control svg{
  2909. cursor: pointer;
  2910. }
  2911. `
  2912. )
  2913. });
  2914. const $search = $alert.$shadowRoot.querySelector(
  2915. ".cookie-search-inner input"
  2916. );
  2917. const $searchSetting = $alert.$shadowRoot.querySelector(
  2918. ".cookie-search-setting"
  2919. );
  2920. const $refresh = $alert.$shadowRoot.querySelector(
  2921. ".cookie-control-refresh"
  2922. );
  2923. const $add = $alert.$shadowRoot.querySelector(
  2924. ".cookie-control-add"
  2925. );
  2926. const $copyAll = $alert.$shadowRoot.querySelector(
  2927. ".cookie-control-copy-all"
  2928. );
  2929. const $clearAll = $alert.$shadowRoot.querySelector(
  2930. ".cookie-control-clear-all"
  2931. );
  2932. const $ruleManager = $alert.$shadowRoot.querySelector(
  2933. ".cookie-control-rule-manager"
  2934. );
  2935. const $setting = $alert.$shadowRoot.querySelector(".cookie-setting");
  2936. const $cookieListWrapper = $alert.$shadowRoot.querySelector(
  2937. ".cookie-list-wrapper"
  2938. );
  2939. let createCookieItemElement = (cookieInfo) => {
  2940. const $cookieItem = domUtils.createElement("div", {
  2941. className: "cookie-item",
  2942. innerHTML: (
  2943. /*html*/
  2944. `
  2945. `
  2946. )
  2947. });
  2948. const cookieProperty = [
  2949. {
  2950. leftText: "name",
  2951. rightText: cookieInfo.name
  2952. },
  2953. {
  2954. leftText: "value",
  2955. rightText: PopsPanel.getValue("decode-cookie-value") ? decodeURIComponent(cookieInfo.value) : encodeURIComponent(cookieInfo.value)
  2956. }
  2957. ];
  2958. if (CookieManager.cookieManagerApiName === "GM_cookie") {
  2959. cookieInfo = cookieInfo;
  2960. cookieProperty.push(
  2961. {
  2962. leftText: "domain",
  2963. rightText: cookieInfo.domain
  2964. },
  2965. {
  2966. leftText: "path",
  2967. rightText: cookieInfo.path
  2968. },
  2969. {
  2970. leftText: "session",
  2971. rightText: JSON.stringify(cookieInfo.session)
  2972. },
  2973. {
  2974. leftText: "expires",
  2975. rightText: cookieInfo.session ? "会话" : cookieInfo.expirationDate ? new Date(cookieInfo.expirationDate * 1e3).toISOString() : "未知"
  2976. },
  2977. {
  2978. leftText: "httpOnly",
  2979. rightText: JSON.stringify(cookieInfo.httpOnly)
  2980. },
  2981. {
  2982. leftText: "hostOnly",
  2983. rightText: JSON.stringify(cookieInfo.hostOnly)
  2984. },
  2985. {
  2986. leftText: "secure",
  2987. rightText: JSON.stringify(cookieInfo.secure)
  2988. },
  2989. {
  2990. leftText: "sameSite",
  2991. rightText: cookieInfo.sameSite
  2992. }
  2993. );
  2994. } else if (CookieManager.cookieManagerApiName === "cookieStore") {
  2995. cookieInfo = cookieInfo;
  2996. cookieProperty.push(
  2997. {
  2998. leftText: "domain",
  2999. rightText: cookieInfo.domain
  3000. },
  3001. {
  3002. leftText: "path",
  3003. rightText: cookieInfo.path
  3004. },
  3005. {
  3006. leftText: "expires",
  3007. rightText: cookieInfo.expires ? new Date(cookieInfo.expires).toISOString() : "未知"
  3008. },
  3009. {
  3010. leftText: "secure",
  3011. rightText: JSON.stringify(cookieInfo.secure)
  3012. },
  3013. {
  3014. leftText: "sameSite",
  3015. rightText: cookieInfo.sameSite
  3016. }
  3017. );
  3018. }
  3019. cookieProperty.forEach((it) => {
  3020. const $cookieItemGroup = domUtils.createElement("div", {
  3021. className: "cookie-item-group",
  3022. innerHTML: (
  3023. /*html*/
  3024. `
  3025. <div class="cookie-item-group-left">
  3026. <p>${it.leftText}</p>
  3027. </div>
  3028. <div class="cookie-item-group-right">
  3029. <p>${it.rightText}</p>
  3030. </div>
  3031. `
  3032. )
  3033. });
  3034. domUtils.append($cookieItem, $cookieItemGroup);
  3035. });
  3036. let $cookieItemGroupControl = domUtils.createElement("div", {
  3037. className: "cookie-item-group cookie-item-group-control",
  3038. innerHTML: (
  3039. /*html*/
  3040. `
  3041. <div class="cookie-item-group-left">操作</div>
  3042. <div class="cookie-item-group-right">
  3043. <div class="cookie-item-group-control-copy">
  3044. <svg t="1742795616339" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
  3045. <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>
  3046. </svg>
  3047. </div>
  3048. <div class="cookie-item-group-control-edit">
  3049. <svg t="1742795710451" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
  3050. <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>
  3051. </svg>
  3052. </div>
  3053. <div class="cookie-item-group-control-delete">
  3054. ${__pops.config.iconSVG.delete}
  3055. </div>
  3056. </div>
  3057. `
  3058. )
  3059. });
  3060. let $cookieItemCopy = $cookieItemGroupControl.querySelector(
  3061. ".cookie-item-group-control-copy"
  3062. );
  3063. let $cookieItemEdit = $cookieItemGroupControl.querySelector(
  3064. ".cookie-item-group-control-edit"
  3065. );
  3066. let $cookieItemDelete = $cookieItemGroupControl.querySelector(
  3067. ".cookie-item-group-control-delete"
  3068. );
  3069. domUtils.on($cookieItemCopy, "click", (event) => {
  3070. utils.preventEvent(event);
  3071. let cookieText = cookieInfo.value;
  3072. utils.setClip(cookieText).then((status) => {
  3073. if (status) {
  3074. Qmsg.success("复制成功");
  3075. } else {
  3076. Qmsg.error("复制失败");
  3077. }
  3078. });
  3079. });
  3080. domUtils.on($cookieItemEdit, "click", (event) => {
  3081. utils.preventEvent(event);
  3082. CookieManagerEditView.showView(cookieInfo, (__cookieInfo__) => {
  3083. var _a2;
  3084. let $newCookieItem = createCookieItemElement(__cookieInfo__);
  3085. domUtils.after($cookieItem, $newCookieItem);
  3086. (_a2 = $cookieItem.parentElement) == null ? void 0 : _a2.removeChild($cookieItem);
  3087. });
  3088. });
  3089. domUtils.on($cookieItemDelete, "click", (event) => {
  3090. utils.preventEvent(event);
  3091. let result = confirm("确定删除该Cookie?");
  3092. if (!result) {
  3093. return;
  3094. }
  3095. CookieManager.deleteCookie(cookieInfo).then((status) => {
  3096. var _a2;
  3097. if (!status) {
  3098. Qmsg.success("删除成功");
  3099. (_a2 = $cookieItem.parentElement) == null ? void 0 : _a2.removeChild($cookieItem);
  3100. } else {
  3101. log.error(status);
  3102. Qmsg.error("删除失败");
  3103. }
  3104. });
  3105. });
  3106. domUtils.append($cookieItem, [$cookieItemGroupControl]);
  3107. return $cookieItem;
  3108. };
  3109. let updateCookieListGroup = async (filterCallBack) => {
  3110. let cookieList = await CookieManager.queryAllCookie();
  3111. if (typeof filterCallBack === "function") {
  3112. cookieList = cookieList.filter(filterCallBack);
  3113. }
  3114. domUtils.empty($cookieListWrapper);
  3115. let $fragment = document.createDocumentFragment();
  3116. cookieList.forEach((cookieItem) => {
  3117. if (
  3118. // @ts-ignore
  3119. cookieItem.session && PopsPanel.getValue("exclude-session-cookie")
  3120. ) {
  3121. return;
  3122. }
  3123. const $cookieItem = createCookieItemElement(cookieItem);
  3124. domUtils.append($fragment, $cookieItem);
  3125. });
  3126. domUtils.append($cookieListWrapper, $fragment);
  3127. };
  3128. updateCookieListGroup();
  3129. domUtils.on(
  3130. $search,
  3131. ["input", "propertychange"],
  3132. utils.debounce((event) => {
  3133. updateCookieListGroup((cookieItem) => {
  3134. let searchText = domUtils.val($search);
  3135. let enableRegExp = PopsPanel.getValue(
  3136. "search-config-use-regexp"
  3137. );
  3138. return enableRegExp ? Boolean(cookieItem.name.match(new RegExp(searchText))) : cookieItem.name.includes(searchText);
  3139. });
  3140. })
  3141. );
  3142. domUtils.listenKeyboard(
  3143. $search,
  3144. "keypress",
  3145. (keyName, keyValue, otherCodeList) => {
  3146. if (keyName === "Enter" && otherCodeList.length === 0) {
  3147. utils.dispatchEvent($search, "input");
  3148. }
  3149. }
  3150. );
  3151. domUtils.on($searchSetting, "click", (event) => {
  3152. utils.preventEvent(event);
  3153. let $settingAlert = __pops.alert({
  3154. title: {
  3155. text: "搜索配置",
  3156. position: "center"
  3157. },
  3158. content: {
  3159. text: "",
  3160. html: true
  3161. },
  3162. btn: {
  3163. ok: {
  3164. enable: false
  3165. }
  3166. },
  3167. drag: true,
  3168. mask: {
  3169. clickEvent: {
  3170. toClose: true
  3171. }
  3172. },
  3173. width: PanelUISize.info.width,
  3174. height: PanelUISize.info.height,
  3175. style: (
  3176. /*css*/
  3177. `
  3178. ${__pops.config.cssText.panelCSS}
  3179.  
  3180. .pops-alert-content li{
  3181. display: flex;
  3182. justify-content: space-between;
  3183. align-items: center;
  3184. padding: 10px;
  3185. }
  3186. .pops-panel-item-left-desc-text{
  3187. line-height: normal;
  3188. margin-top: 6px;
  3189. font-size: 0.8em;
  3190. color: rgb(108, 108, 108);
  3191. }
  3192. `
  3193. )
  3194. });
  3195. let $content = $settingAlert.$shadowRoot.querySelector(
  3196. ".pops-alert-content"
  3197. );
  3198. let panelHandleContentUtils = __pops.config.panelHandleContentUtils();
  3199. let $useRegExp = panelHandleContentUtils.createSectionContainerItem_switch(
  3200. UISwitch(
  3201. "启用正则表达式",
  3202. "search-config-use-regexp",
  3203. false,
  3204. void 0,
  3205. "使用正则表达式搜索Cookie名称"
  3206. )
  3207. );
  3208. domUtils.append($content, $useRegExp);
  3209. });
  3210. domUtils.on($refresh, "click", (event) => {
  3211. utils.preventEvent(event);
  3212. let searchText = domUtils.val($search);
  3213. if (searchText == "") {
  3214. updateCookieListGroup();
  3215. } else {
  3216. utils.dispatchEvent($search, "input");
  3217. }
  3218. });
  3219. domUtils.on($add, "click", (event) => {
  3220. utils.preventEvent(event);
  3221. CookieManagerEditView.showView(void 0, (__cookieInfo__) => {
  3222. updateCookieListGroup();
  3223. });
  3224. });
  3225. domUtils.on($copyAll, "click", (event) => {
  3226. utils.preventEvent(event);
  3227. CookieManager.queryAllCookie().then((cookieList) => {
  3228. cookieList = cookieList.filter((it) => {
  3229. return !(it.session && PopsPanel.getValue("exclude-session-cookie"));
  3230. });
  3231. if (cookieList.length === 0) {
  3232. Qmsg.warning("没有Cookie可以复制");
  3233. return;
  3234. }
  3235. let cookieText = cookieList.map((it) => {
  3236. let cookieItemValueText = it.value;
  3237. return `${it.name}=${cookieItemValueText}; `;
  3238. }).join("");
  3239. utils.setClip(cookieText).then((status) => {
  3240. if (status) {
  3241. Qmsg.success("复制成功");
  3242. } else {
  3243. Qmsg.error("复制失败");
  3244. }
  3245. });
  3246. });
  3247. });
  3248. domUtils.on($clearAll, "click", (event) => {
  3249. utils.preventEvent(event);
  3250. let result = window.confirm("确定清除全部Cookie?");
  3251. if (!result) {
  3252. return;
  3253. }
  3254. CookieManager.deleteAllCookie().then((deleteInfo) => {
  3255. if (deleteInfo.error) {
  3256. Qmsg.warning(
  3257. `清除成功:${deleteInfo.success} 失败:${deleteInfo.error}`
  3258. );
  3259. } else {
  3260. Qmsg.success("清除成功");
  3261. }
  3262. updateCookieListGroup();
  3263. });
  3264. });
  3265. domUtils.on($ruleManager, "click", (event) => {
  3266. utils.preventEvent(event);
  3267. CookieRule.showView();
  3268. });
  3269. domUtils.on($setting, "click", (event) => {
  3270. utils.preventEvent(event);
  3271. let $settingAlert = __pops.alert({
  3272. title: {
  3273. text: "设置",
  3274. position: "center"
  3275. },
  3276. content: {
  3277. text: "",
  3278. html: true
  3279. },
  3280. btn: {
  3281. ok: {
  3282. enable: false
  3283. }
  3284. },
  3285. drag: true,
  3286. mask: {
  3287. clickEvent: {
  3288. toClose: true
  3289. }
  3290. },
  3291. width: PanelUISize.info.width,
  3292. height: PanelUISize.info.height,
  3293. style: (
  3294. /*css*/
  3295. `
  3296. ${__pops.config.cssText.panelCSS}
  3297.  
  3298. .pops-alert-content li{
  3299. display: flex;
  3300. justify-content: space-between;
  3301. align-items: center;
  3302. padding: 10px;
  3303. }
  3304. .pops-panel-item-left-desc-text{
  3305. line-height: normal;
  3306. margin-top: 6px;
  3307. font-size: 0.8em;
  3308. color: rgb(108, 108, 108);
  3309. }
  3310. `
  3311. )
  3312. });
  3313. let $content = $settingAlert.$shadowRoot.querySelector(
  3314. ".pops-alert-content"
  3315. );
  3316. let panelHandleContentUtils = __pops.config.panelHandleContentUtils();
  3317. let $useGM_cookie = panelHandleContentUtils.createSectionContainerItem_select(
  3318. UISelect(
  3319. "CookieManager Api",
  3320. "cookie-manager-api",
  3321. "document.cookie",
  3322. [
  3323. {
  3324. text: "document.cookie",
  3325. value: "document.cookie"
  3326. },
  3327. {
  3328. text: "cookieStore",
  3329. value: "cookieStore"
  3330. },
  3331. {
  3332. text: "GM_cookie",
  3333. value: "GM_cookie"
  3334. }
  3335. ],
  3336. () => {
  3337. updateCookieListGroup();
  3338. },
  3339. "操作Cookie的Api函数"
  3340. )
  3341. );
  3342. let $decodeValue = panelHandleContentUtils.createSectionContainerItem_switch(
  3343. UISwitch(
  3344. "解码Cookie值",
  3345. "decode-cookie-value",
  3346. false,
  3347. () => {
  3348. updateCookieListGroup();
  3349. },
  3350. "对Cookie值进行解码"
  3351. )
  3352. );
  3353. let $excludeSessionCookie = panelHandleContentUtils.createSectionContainerItem_switch(
  3354. UISwitch(
  3355. "排除Session Cookie",
  3356. "exclude-session-cookie",
  3357. false,
  3358. () => {
  3359. updateCookieListGroup();
  3360. },
  3361. "过滤掉浏览器会话Cookie"
  3362. )
  3363. );
  3364. domUtils.append($content, [
  3365. $useGM_cookie,
  3366. $decodeValue,
  3367. $excludeSessionCookie
  3368. ]);
  3369. });
  3370. },
  3371. /**
  3372. * 注册(不可用)脚本菜单
  3373. */
  3374. registerMenu() {
  3375. const that = this;
  3376. GM_Menu.add({
  3377. key: "cookie_manager_view",
  3378. text: "⚙ Cookie管理",
  3379. autoReload: false,
  3380. isStoreValue: false,
  3381. showText(text, enable) {
  3382. return text;
  3383. },
  3384. callback(data) {
  3385. that.showView();
  3386. }
  3387. });
  3388. }
  3389. };
  3390. const CookieRuleController = {
  3391. init() {
  3392. this.execController();
  3393. domUtils.ready(() => {
  3394. this.execController();
  3395. });
  3396. },
  3397. /**
  3398. * 执行操作
  3399. */
  3400. execController() {
  3401. for (let index = 0; index < CookieRule.$data.ruleData.length; index++) {
  3402. const rule = CookieRule.$data.ruleData[index];
  3403. CookieManager.queryAllCookie().then(async (cookieListResult) => {
  3404. for (let cookieInfoIndex = 0; cookieInfoIndex < cookieListResult.length; cookieInfoIndex++) {
  3405. let cookieInfo = cookieListResult[cookieInfoIndex];
  3406. const cookieName = cookieInfo.name;
  3407. const ruleCookieName = rule.data.cookieName;
  3408. let flag = false;
  3409. if (rule.data.enableRegExpToMatchCookieName) {
  3410. let regExpCookieName = new RegExp(ruleCookieName, "i");
  3411. if (regExpCookieName.test(cookieName)) {
  3412. flag = true;
  3413. }
  3414. } else {
  3415. if (cookieName.includes(ruleCookieName)) {
  3416. flag = true;
  3417. }
  3418. }
  3419. if (flag) {
  3420. let operationMode = rule.data.operationMode;
  3421. if (operationMode === "delete") {
  3422. CookieManager.deleteCookie(cookieInfo);
  3423. } else if (operationMode === "extended" || operationMode === "extended-90" || operationMode === "extended-180" || operationMode === "extended-360") {
  3424. let currentTime = Date.now();
  3425. let oneMonth = 30 * 24 * 60 * 60 * 1e3;
  3426. let threeMonth = oneMonth * 3;
  3427. let halfAYear = oneMonth * 6;
  3428. let oneYear = oneMonth * 12;
  3429. let checkTime = oneMonth;
  3430. if (operationMode === "extended-90") {
  3431. checkTime = threeMonth;
  3432. } else if (operationMode === "extended-180") {
  3433. checkTime = halfAYear;
  3434. } else if (operationMode === "extended-360") {
  3435. checkTime = oneYear;
  3436. }
  3437. let updateFlag = false;
  3438. if (CookieManager.cookieManagerApiName === "document.cookie") {
  3439. cookieInfo.expirationDate = currentTime + checkTime;
  3440. updateFlag = true;
  3441. } else if (CookieManager.cookieManagerApiName === "cookieStore") {
  3442. let expireTime = cookieInfo.expires;
  3443. if (typeof expireTime === "number" && expireTime - currentTime < checkTime) {
  3444. cookieInfo.expires = expireTime + checkTime;
  3445. updateFlag = true;
  3446. }
  3447. } else if (CookieManager.cookieManagerApiName === "GM_cookie") {
  3448. let expireTime = cookieInfo.expirationDate;
  3449. if (typeof expireTime === "number" && expireTime * 1e3 - currentTime < checkTime) {
  3450. cookieInfo.expirationDate = expireTime + checkTime / 1e3;
  3451. updateFlag = true;
  3452. }
  3453. } else {
  3454. log.error(
  3455. "未知的cookieManagerApiName",
  3456. CookieManager.cookieManagerApiName
  3457. );
  3458. }
  3459. if (updateFlag) {
  3460. await CookieManager.updateCookie(cookieInfo);
  3461. }
  3462. }
  3463. }
  3464. }
  3465. });
  3466. }
  3467. }
  3468. };
  3469. PopsPanel.init();
  3470. CookieRule.init();
  3471. CookieRuleController.init();
  3472. CookieManagerView.init();
  3473.  
  3474. })(Qmsg, DOMUtils, Utils, pops);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址