CookieManager

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

  1. // ==UserScript==
  2. // @name CookieManager
  3. // @namespace https://github.com/WhiteSevs/TamperMonkeyScript
  4. // @version 2025.4.23
  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.5/dist/index.umd.js
  13. // @require https://fastly.jsdelivr.net/npm/@whitesev/domutils@1.5.3/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.1/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. const CookieInfoTransform = {
  2411. /**
  2412. * 对编辑前的cookie信息进行值转换
  2413. */
  2414. beforeEdit(cookieInfo) {
  2415. const cookieManagerApiName = CookieManager.cookieManagerApiName;
  2416. if (cookieManagerApiName === "cookieStore") {
  2417. if (typeof cookieInfo.expires === "number") {
  2418. cookieInfo.expirationDate = cookieInfo.expires;
  2419. }
  2420. } else if (cookieManagerApiName === "GM_cookie") {
  2421. if (typeof cookieInfo.expirationDate === "number") {
  2422. cookieInfo.expirationDate = cookieInfo.expirationDate * 1e3;
  2423. }
  2424. }
  2425. return cookieInfo;
  2426. },
  2427. /**
  2428. * 对编辑后的cookie信息进行值转换
  2429. */
  2430. afterEdit(cookieInfo) {
  2431. const cookieManagerApiName = CookieManager.cookieManagerApiName;
  2432. if (cookieManagerApiName === "document.cookie") {
  2433. cookieInfo.domain = "";
  2434. } else if (cookieManagerApiName === "cookieStore") {
  2435. if (typeof cookieInfo.expirationDate === "number") {
  2436. cookieInfo.expires = cookieInfo.expirationDate;
  2437. }
  2438. } else if (cookieManagerApiName === "GM_cookie") {
  2439. if (typeof cookieInfo.expirationDate === "number") {
  2440. cookieInfo.expirationDate = Math.floor(
  2441. cookieInfo.expirationDate / 1e3
  2442. );
  2443. }
  2444. }
  2445. return cookieInfo;
  2446. }
  2447. };
  2448. let edit_ui_input = (text, getValue, setValue, disabled) => {
  2449. let config = {
  2450. text,
  2451. type: "input",
  2452. isNumber: false,
  2453. isPassword: false,
  2454. props: {},
  2455. attributes: {},
  2456. description: "",
  2457. getValue() {
  2458. return getValue();
  2459. },
  2460. callback(event, value) {
  2461. setValue(value);
  2462. },
  2463. placeholder: "",
  2464. disabled: Boolean(disabled)
  2465. };
  2466. return config;
  2467. };
  2468. let edit_ui_select = (text, data, getValue, setValue, disabled) => {
  2469. let config = {
  2470. text,
  2471. type: "select",
  2472. description: "",
  2473. attributes: {},
  2474. props: {},
  2475. getValue() {
  2476. return getValue();
  2477. },
  2478. callback(event, isSelectedValue, isSelectedText) {
  2479. let value = isSelectedValue;
  2480. setValue(value);
  2481. },
  2482. // @ts-ignore
  2483. data,
  2484. disabled: Boolean(disabled)
  2485. };
  2486. return config;
  2487. };
  2488. const CookieManagerEditView = {
  2489. init() {
  2490. },
  2491. /**
  2492. * 显示视图
  2493. * @param cookieInfo 需要编辑的cookie
  2494. * @param dialogCloseCallBack 弹窗关闭的回调
  2495. */
  2496. showView(__cookieInfo__, dialogCloseCallBack) {
  2497. let isEdit = !!__cookieInfo__;
  2498. let cookieInfo = utils.assign(
  2499. {
  2500. name: "",
  2501. value: "",
  2502. domain: window.location.hostname,
  2503. path: "/",
  2504. secure: false,
  2505. hostOnly: false,
  2506. httpOnly: false,
  2507. sameSite: "lax",
  2508. expirationDate: Date.now() + 60 * 60 * 24 * 30 * 1e3
  2509. },
  2510. __cookieInfo__,
  2511. true
  2512. );
  2513. cookieInfo = CookieInfoTransform.beforeEdit(cookieInfo);
  2514. let $dialog = __pops.confirm({
  2515. title: {
  2516. text: isEdit ? "编辑Cookie" : "添加Cookie",
  2517. position: "center"
  2518. },
  2519. content: {
  2520. text: "",
  2521. html: true
  2522. },
  2523. drag: true,
  2524. btn: {
  2525. position: "center",
  2526. ok: {
  2527. text: isEdit ? "编辑" : "添加",
  2528. async callback(eventDetails, event) {
  2529. let valid = CookieManagerEditView.validCookieInfo(cookieInfo);
  2530. if (!valid) {
  2531. return;
  2532. }
  2533. cookieInfo.value = encodeURIComponent(cookieInfo.value);
  2534. cookieInfo = CookieInfoTransform.afterEdit(cookieInfo);
  2535. if (isEdit) {
  2536. let result = await CookieManager.updateCookie(cookieInfo);
  2537. if (result) {
  2538. Qmsg.error(result.toString());
  2539. } else {
  2540. Qmsg.success("修改成功");
  2541. eventDetails.close();
  2542. }
  2543. } else {
  2544. let result = await CookieManager.addCookie(cookieInfo);
  2545. if (result) {
  2546. Qmsg.error(result.toString());
  2547. } else {
  2548. Qmsg.success("添加成功");
  2549. eventDetails.close();
  2550. }
  2551. }
  2552. if (typeof dialogCloseCallBack === "function") {
  2553. dialogCloseCallBack(cookieInfo);
  2554. }
  2555. }
  2556. },
  2557. cancel: {
  2558. text: "取消"
  2559. }
  2560. },
  2561. mask: {
  2562. enable: true
  2563. },
  2564. width: window.innerWidth > 350 ? "350px" : "80vw",
  2565. height: PanelUISize.setting.height,
  2566. style: (
  2567. /*css*/
  2568. `
  2569. ${__pops.config.cssText.panelCSS}
  2570.  
  2571. .pops-panel-input input:disabled{
  2572. color: #b4b4b4;
  2573. }
  2574. .pops-confirm-content{
  2575. padding: 10px;
  2576. }
  2577. .pops-confirm-content li{
  2578. display: flex;
  2579. flex-direction: column;
  2580. }
  2581. .pops-panel-item-left-text{
  2582. margin-bottom: 5px;
  2583. }
  2584. .pops-panel-input.pops-input-disabled{
  2585. border: 1px solid #dcdfe6;
  2586. }
  2587. #cookie-item-property-expires{
  2588. border: 1px solid rgb(184, 184, 184, var(--pops-bd-opacity));
  2589. border-radius: 4px;
  2590. background-color: #ffffff;
  2591. width: 100%;
  2592. height: 32px;
  2593. padding: 0px 8px;
  2594. }
  2595. #cookie-item-property-expires:hover{
  2596. box-shadow: 0 0 0 1px #c0c4cc inset;
  2597. }
  2598. #cookie-item-property-expires:focus,
  2599. #cookie-item-property-expires:focus-within{
  2600. outline: 0;
  2601. border: 1px solid #409eff;
  2602. border-radius: 4px;
  2603. box-shadow: none;
  2604. }
  2605. `
  2606. )
  2607. });
  2608. let $editContent = $dialog.$shadowRoot.querySelector(
  2609. ".pops-confirm-content"
  2610. );
  2611. let panelHandleContentUtils = __pops.config.panelHandleContentUtils();
  2612. let $name = panelHandleContentUtils.createSectionContainerItem_input(
  2613. edit_ui_input(
  2614. "name",
  2615. () => cookieInfo.name,
  2616. (value) => cookieInfo.name = value,
  2617. isEdit
  2618. )
  2619. );
  2620. let $value = panelHandleContentUtils.createSectionContainerItem_input(
  2621. edit_ui_input(
  2622. "value",
  2623. () => cookieInfo.value,
  2624. (value) => cookieInfo.value = value
  2625. )
  2626. );
  2627. let $domain = panelHandleContentUtils.createSectionContainerItem_input(
  2628. edit_ui_input(
  2629. "domain",
  2630. () => cookieInfo.domain,
  2631. (value) => cookieInfo.domain = value
  2632. )
  2633. );
  2634. let $path = panelHandleContentUtils.createSectionContainerItem_input(
  2635. edit_ui_input(
  2636. "path",
  2637. () => cookieInfo.path,
  2638. (value) => cookieInfo.path = value
  2639. )
  2640. );
  2641. let $expires;
  2642. if (cookieInfo.session) {
  2643. $expires = panelHandleContentUtils.createSectionContainerItem_input(
  2644. edit_ui_input(
  2645. "expires",
  2646. () => "会话",
  2647. (value) => {
  2648. },
  2649. true
  2650. )
  2651. );
  2652. } else {
  2653. $expires = panelHandleContentUtils.createSectionContainerItem_own({
  2654. type: "own",
  2655. getLiElementCallBack: function(liElement) {
  2656. let $li = domUtils.createElement("li", {
  2657. innerHTML: (
  2658. /*html*/
  2659. `
  2660. <div class="pops-panel-item-left-text">
  2661. <p class="pops-panel-item-left-main-text">expires</p>
  2662. </div>
  2663. <div class="pops-panel-item-right-wrapper">
  2664. <input type="datetime-local" id="cookie-item-property-expires">
  2665. </div>
  2666. `
  2667. )
  2668. });
  2669. let $dateTime = $li.querySelector(
  2670. "#cookie-item-property-expires"
  2671. );
  2672. $dateTime.valueAsNumber = cookieInfo.expirationDate;
  2673. domUtils.on(
  2674. $dateTime,
  2675. ["change", "input", "propertychange"],
  2676. (event) => {
  2677. utils.preventEvent(event);
  2678. cookieInfo.expirationDate = $dateTime.valueAsNumber;
  2679. }
  2680. );
  2681. return $li;
  2682. }
  2683. });
  2684. }
  2685. let $httpOnly = panelHandleContentUtils.createSectionContainerItem_select(
  2686. edit_ui_select(
  2687. "httpOnly",
  2688. [
  2689. {
  2690. text: "true",
  2691. value: true
  2692. },
  2693. {
  2694. text: "false",
  2695. value: false
  2696. }
  2697. ],
  2698. () => cookieInfo.httpOnly,
  2699. (value) => cookieInfo.httpOnly = value
  2700. )
  2701. );
  2702. let $secure = panelHandleContentUtils.createSectionContainerItem_select(
  2703. edit_ui_select(
  2704. "secure",
  2705. [
  2706. {
  2707. text: "true",
  2708. value: true
  2709. },
  2710. {
  2711. text: "false",
  2712. value: false
  2713. }
  2714. ],
  2715. () => cookieInfo.secure,
  2716. (value) => cookieInfo.secure = value
  2717. )
  2718. );
  2719. let sameSiteData = [
  2720. {
  2721. text: "no_restriction",
  2722. value: "no_restriction"
  2723. },
  2724. {
  2725. text: "lax",
  2726. value: "lax"
  2727. },
  2728. {
  2729. text: "strict",
  2730. value: "strict"
  2731. },
  2732. {
  2733. text: "unspecified",
  2734. value: "unspecified"
  2735. }
  2736. ];
  2737. if (CookieManager.cookieManagerApiName === "cookieStore") {
  2738. sameSiteData = [
  2739. {
  2740. text: "lax",
  2741. value: "lax"
  2742. },
  2743. {
  2744. text: "strict",
  2745. value: "strict"
  2746. },
  2747. {
  2748. text: "none",
  2749. value: "none"
  2750. }
  2751. ];
  2752. }
  2753. let $sameSite = panelHandleContentUtils.createSectionContainerItem_select(
  2754. edit_ui_select(
  2755. "sameSite",
  2756. sameSiteData,
  2757. () => cookieInfo.sameSite,
  2758. (value) => cookieInfo.sameSite = value
  2759. )
  2760. );
  2761. domUtils.append($editContent, [$name, $value]);
  2762. if (CookieManager.cookieManagerApiName === "GM_cookie") {
  2763. domUtils.append($editContent, [
  2764. $domain,
  2765. $path,
  2766. $expires,
  2767. $httpOnly,
  2768. $secure,
  2769. $sameSite
  2770. ]);
  2771. } else if (CookieManager.cookieManagerApiName === "cookieStore") {
  2772. domUtils.append($editContent, [$domain, $path, $expires, $sameSite]);
  2773. }
  2774. },
  2775. /**
  2776. * Cookie信息校验
  2777. */
  2778. validCookieInfo(cookieInfo) {
  2779. if (cookieInfo.name == null || cookieInfo.name == "") {
  2780. Qmsg.error("name不能为空");
  2781. return false;
  2782. }
  2783. if (cookieInfo.domain == null || cookieInfo.domain == "") {
  2784. Qmsg.error("domain不能为空");
  2785. return false;
  2786. }
  2787. if (cookieInfo.path == null || cookieInfo.path == "") {
  2788. Qmsg.error("path不能为空");
  2789. return false;
  2790. }
  2791. return true;
  2792. }
  2793. };
  2794. const CookieManagerView = {
  2795. init() {
  2796. this.registerMenu();
  2797. },
  2798. /**
  2799. * 显示视图
  2800. */
  2801. async showView() {
  2802. const $alert = __pops.alert({
  2803. title: {
  2804. text: "Cookie编辑器",
  2805. html: false,
  2806. position: "center"
  2807. },
  2808. content: {
  2809. text: (
  2810. /*html*/
  2811. `
  2812. <div class="cookie-wrapper">
  2813. <div class="cookie-search-wrapper">
  2814. <div class="cookie-search-inner">
  2815. <input type="text" placeholder="搜索Cookie名称">
  2816. </div>
  2817. <div class="cookie-search-setting">
  2818. <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">
  2819. <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>
  2820. </svg>
  2821. </div>
  2822. </div>
  2823. <div class="cookie-control-wrapper">
  2824. <button class="cookie-control-refresh" type="default">刷新</button>
  2825. <button class="cookie-control-add" type="default">添加</button>
  2826. <button class="cookie-control-copy-all" type="default">复制全部</button>
  2827. <button class="cookie-control-clear-all" type="default">清除全部</button>
  2828. <button class="cookie-control-rule-manager" type="default">规则管理</button>
  2829. <div class="cookie-setting">
  2830. <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">
  2831. <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>
  2832. </svg>
  2833. </div>
  2834. </div>
  2835. <div class="cookie-list-wrapper">
  2836. </div>
  2837. </div>
  2838. `
  2839. ),
  2840. html: true
  2841. },
  2842. btn: {
  2843. ok: {
  2844. enable: false
  2845. }
  2846. },
  2847. mask: {
  2848. enable: true
  2849. },
  2850. drag: true,
  2851. width: PanelUISize.setting.width,
  2852. height: PanelUISize.setting.height,
  2853. style: (
  2854. /*css*/
  2855. `
  2856. ${__pops.config.cssText.panelCSS}
  2857. .cookie-wrapper{
  2858. display: flex;
  2859. flex-direction: column;
  2860. padding: 10px;
  2861. gap: 10px;
  2862. }
  2863. .cookie-control-wrapper{
  2864. display: flex;
  2865. flex-wrap: wrap;
  2866. padding: 0px 10px;
  2867. gap: 5px;
  2868. --button-margin-left: 0px;
  2869. }
  2870. .cookie-search-wrapper{
  2871. display: flex;
  2872. align-items: center;
  2873. }
  2874. .cookie-search-inner{
  2875. width: 100%;
  2876. padding: 0px 10px;
  2877. }
  2878. .cookie-search-inner input{
  2879. height: 30px;
  2880. padding: 5px;
  2881. width: 100%;
  2882. }
  2883. .cookie-search-inner input:focus-visible{
  2884. outline: none;
  2885. }
  2886. .cookie-setting,
  2887. .cookie-search-setting{
  2888. display: flex;
  2889. align-items: center;
  2890. }
  2891. .cookie-setting svg,
  2892. .cookie-search-setting svg{
  2893. cursor: pointer;
  2894. }
  2895. .cookie-list-wrapper{
  2896. display: flex;
  2897. flex-wrap: wrap;
  2898. gap: 10px;
  2899. }
  2900. .cookie-item{
  2901. display: flex;
  2902. flex-direction: column;
  2903. padding: 10px 10px;
  2904. margin: 0px 10px;
  2905. background: #f1efef;
  2906. border-radius: 10px;
  2907. gap: 5px;
  2908. box-sizing: border-box;
  2909. width: 100%;
  2910. }
  2911. .cookie-item-group{
  2912. display: flex;
  2913. align-items: center;
  2914. }
  2915. .cookie-item-group-left{
  2916. width: 100px;
  2917. min-width: 100px;
  2918. max-width: 100px;
  2919. text-transform: capitalize
  2920. }
  2921. .cookie-item-group-control .cookie-item-group-right{
  2922. display: flex;
  2923. align-items: center;
  2924. gap: 10px;
  2925. }
  2926. .cookie-item-group-control .cookie-item-group-control-copy,
  2927. .cookie-item-group-control .cookie-item-group-control-edit,
  2928. .cookie-item-group-control .cookie-item-group-control-delete{
  2929. display: flex;
  2930. align-items: center;
  2931. }
  2932. .cookie-item-group-control .cookie-item-group-control-delete svg{
  2933. width: 16px;
  2934. height: 16px;
  2935. }
  2936. .cookie-item-group-control svg{
  2937. cursor: pointer;
  2938. }
  2939. `
  2940. )
  2941. });
  2942. const $search = $alert.$shadowRoot.querySelector(
  2943. ".cookie-search-inner input"
  2944. );
  2945. const $searchSetting = $alert.$shadowRoot.querySelector(
  2946. ".cookie-search-setting"
  2947. );
  2948. const $refresh = $alert.$shadowRoot.querySelector(
  2949. ".cookie-control-refresh"
  2950. );
  2951. const $add = $alert.$shadowRoot.querySelector(
  2952. ".cookie-control-add"
  2953. );
  2954. const $copyAll = $alert.$shadowRoot.querySelector(
  2955. ".cookie-control-copy-all"
  2956. );
  2957. const $clearAll = $alert.$shadowRoot.querySelector(
  2958. ".cookie-control-clear-all"
  2959. );
  2960. const $ruleManager = $alert.$shadowRoot.querySelector(
  2961. ".cookie-control-rule-manager"
  2962. );
  2963. const $setting = $alert.$shadowRoot.querySelector(".cookie-setting");
  2964. const $cookieListWrapper = $alert.$shadowRoot.querySelector(
  2965. ".cookie-list-wrapper"
  2966. );
  2967. let createCookieItemElement = (cookieInfo) => {
  2968. const $cookieItem = domUtils.createElement("div", {
  2969. className: "cookie-item",
  2970. innerHTML: (
  2971. /*html*/
  2972. `
  2973. `
  2974. ),
  2975. "data-cookie-info": cookieInfo
  2976. });
  2977. const cookieProperty = [
  2978. {
  2979. leftText: "name",
  2980. rightText: cookieInfo.name
  2981. },
  2982. {
  2983. leftText: "value",
  2984. // 解码值
  2985. rightText: PopsPanel.getValue("decode-cookie-value") ? decodeURIComponent(cookieInfo.value) : encodeURIComponent(cookieInfo.value)
  2986. }
  2987. ];
  2988. if (CookieManager.cookieManagerApiName === "GM_cookie") {
  2989. cookieInfo = cookieInfo;
  2990. cookieProperty.push(
  2991. {
  2992. leftText: "domain",
  2993. rightText: cookieInfo.domain
  2994. },
  2995. {
  2996. leftText: "path",
  2997. rightText: cookieInfo.path
  2998. },
  2999. {
  3000. leftText: "session",
  3001. rightText: JSON.stringify(cookieInfo.session)
  3002. },
  3003. {
  3004. leftText: "expires",
  3005. rightText: cookieInfo.session ? "会话" : cookieInfo.expirationDate ? new Date(cookieInfo.expirationDate * 1e3).toISOString() : "未知"
  3006. },
  3007. {
  3008. leftText: "httpOnly",
  3009. rightText: JSON.stringify(cookieInfo.httpOnly)
  3010. },
  3011. {
  3012. leftText: "hostOnly",
  3013. rightText: JSON.stringify(cookieInfo.hostOnly)
  3014. },
  3015. {
  3016. leftText: "secure",
  3017. rightText: JSON.stringify(cookieInfo.secure)
  3018. },
  3019. {
  3020. leftText: "sameSite",
  3021. rightText: cookieInfo.sameSite
  3022. }
  3023. );
  3024. } else if (CookieManager.cookieManagerApiName === "cookieStore") {
  3025. cookieInfo = cookieInfo;
  3026. cookieProperty.push(
  3027. {
  3028. leftText: "domain",
  3029. rightText: cookieInfo.domain
  3030. },
  3031. {
  3032. leftText: "path",
  3033. rightText: cookieInfo.path
  3034. },
  3035. {
  3036. leftText: "expires",
  3037. rightText: cookieInfo.expires ? new Date(cookieInfo.expires).toISOString() : "会话"
  3038. },
  3039. {
  3040. leftText: "secure",
  3041. rightText: JSON.stringify(cookieInfo.secure)
  3042. },
  3043. {
  3044. leftText: "sameSite",
  3045. rightText: cookieInfo.sameSite
  3046. }
  3047. );
  3048. }
  3049. cookieProperty.forEach((it) => {
  3050. const $cookieItemGroup = domUtils.createElement("div", {
  3051. className: "cookie-item-group",
  3052. innerHTML: (
  3053. /*html*/
  3054. `
  3055. <div class="cookie-item-group-left">
  3056. <p>${it.leftText}</p>
  3057. </div>
  3058. <div class="cookie-item-group-right">
  3059. <p>${it.rightText}</p>
  3060. </div>
  3061. `
  3062. )
  3063. });
  3064. domUtils.append($cookieItem, $cookieItemGroup);
  3065. });
  3066. let $cookieItemGroupControl = domUtils.createElement("div", {
  3067. className: "cookie-item-group cookie-item-group-control",
  3068. innerHTML: (
  3069. /*html*/
  3070. `
  3071. <div class="cookie-item-group-left">操作</div>
  3072. <div class="cookie-item-group-right">
  3073. <div class="cookie-item-group-control-copy">
  3074. <svg t="1742795616339" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
  3075. <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>
  3076. </svg>
  3077. </div>
  3078. <div class="cookie-item-group-control-edit">
  3079. <svg t="1742795710451" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
  3080. <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>
  3081. </svg>
  3082. </div>
  3083. <div class="cookie-item-group-control-delete">
  3084. ${__pops.config.iconSVG.delete}
  3085. </div>
  3086. </div>
  3087. `
  3088. )
  3089. });
  3090. let $cookieItemCopy = $cookieItemGroupControl.querySelector(
  3091. ".cookie-item-group-control-copy"
  3092. );
  3093. let $cookieItemEdit = $cookieItemGroupControl.querySelector(
  3094. ".cookie-item-group-control-edit"
  3095. );
  3096. let $cookieItemDelete = $cookieItemGroupControl.querySelector(
  3097. ".cookie-item-group-control-delete"
  3098. );
  3099. domUtils.on($cookieItemCopy, "click", (event) => {
  3100. utils.preventEvent(event);
  3101. let cookieText = cookieInfo.value;
  3102. utils.setClip(cookieText).then((status) => {
  3103. if (status) {
  3104. Qmsg.success("复制成功");
  3105. } else {
  3106. Qmsg.error("复制失败");
  3107. }
  3108. });
  3109. });
  3110. domUtils.on($cookieItemEdit, "click", (event) => {
  3111. utils.preventEvent(event);
  3112. CookieManagerEditView.showView(cookieInfo, (__cookieInfo__) => {
  3113. var _a2;
  3114. let $newCookieItem = createCookieItemElement(__cookieInfo__);
  3115. domUtils.after($cookieItem, $newCookieItem);
  3116. (_a2 = $cookieItem.parentElement) == null ? void 0 : _a2.removeChild($cookieItem);
  3117. });
  3118. });
  3119. domUtils.on($cookieItemDelete, "click", (event) => {
  3120. utils.preventEvent(event);
  3121. let result = confirm("确定删除该Cookie?");
  3122. if (!result) {
  3123. return;
  3124. }
  3125. CookieManager.deleteCookie(cookieInfo).then((status) => {
  3126. var _a2;
  3127. if (!status) {
  3128. Qmsg.success("删除成功");
  3129. (_a2 = $cookieItem.parentElement) == null ? void 0 : _a2.removeChild($cookieItem);
  3130. } else {
  3131. log.error(status);
  3132. Qmsg.error("删除失败");
  3133. }
  3134. });
  3135. });
  3136. domUtils.append($cookieItem, [$cookieItemGroupControl]);
  3137. return $cookieItem;
  3138. };
  3139. let updateCookieListGroup = async (filterCallBack) => {
  3140. let cookieList = await CookieManager.queryAllCookie();
  3141. if (typeof filterCallBack === "function") {
  3142. cookieList = cookieList.filter(filterCallBack);
  3143. }
  3144. domUtils.empty($cookieListWrapper);
  3145. let $fragment = document.createDocumentFragment();
  3146. cookieList.forEach((cookieItem) => {
  3147. if (PopsPanel.getValue("exclude-session-cookie")) {
  3148. if (cookieItem.session) {
  3149. return;
  3150. }
  3151. if (CookieManager.cookieManagerApiName === "cookieStore" && // @ts-ignore
  3152. cookieItem.expires == null) {
  3153. return;
  3154. }
  3155. }
  3156. const $cookieItem = createCookieItemElement(cookieItem);
  3157. domUtils.append($fragment, $cookieItem);
  3158. });
  3159. domUtils.append($cookieListWrapper, $fragment);
  3160. };
  3161. updateCookieListGroup();
  3162. domUtils.on(
  3163. $search,
  3164. ["input", "propertychange"],
  3165. utils.debounce((event) => {
  3166. updateCookieListGroup((cookieItem) => {
  3167. let searchText = domUtils.val($search);
  3168. let enableRegExp = PopsPanel.getValue(
  3169. "search-config-use-regexp"
  3170. );
  3171. return enableRegExp ? Boolean(cookieItem.name.match(new RegExp(searchText))) : cookieItem.name.includes(searchText);
  3172. });
  3173. })
  3174. );
  3175. domUtils.listenKeyboard(
  3176. $search,
  3177. "keypress",
  3178. (keyName, keyValue, otherCodeList) => {
  3179. if (keyName === "Enter" && otherCodeList.length === 0) {
  3180. utils.dispatchEvent($search, "input");
  3181. }
  3182. }
  3183. );
  3184. domUtils.on($searchSetting, "click", (event) => {
  3185. utils.preventEvent(event);
  3186. let $settingAlert = __pops.alert({
  3187. title: {
  3188. text: "搜索配置",
  3189. position: "center"
  3190. },
  3191. content: {
  3192. text: "",
  3193. html: true
  3194. },
  3195. btn: {
  3196. ok: {
  3197. enable: false
  3198. }
  3199. },
  3200. drag: true,
  3201. mask: {
  3202. clickEvent: {
  3203. toClose: true
  3204. }
  3205. },
  3206. width: PanelUISize.info.width,
  3207. height: PanelUISize.info.height,
  3208. style: (
  3209. /*css*/
  3210. `
  3211. ${__pops.config.cssText.panelCSS}
  3212.  
  3213. .pops-alert-content li{
  3214. display: flex;
  3215. justify-content: space-between;
  3216. align-items: center;
  3217. padding: 10px;
  3218. }
  3219. .pops-panel-item-left-desc-text{
  3220. line-height: normal;
  3221. margin-top: 6px;
  3222. font-size: 0.8em;
  3223. color: rgb(108, 108, 108);
  3224. }
  3225. `
  3226. )
  3227. });
  3228. let $content = $settingAlert.$shadowRoot.querySelector(
  3229. ".pops-alert-content"
  3230. );
  3231. let panelHandleContentUtils = __pops.config.panelHandleContentUtils();
  3232. let $useRegExp = panelHandleContentUtils.createSectionContainerItem_switch(
  3233. UISwitch(
  3234. "启用正则表达式",
  3235. "search-config-use-regexp",
  3236. false,
  3237. void 0,
  3238. "使用正则表达式搜索Cookie名称"
  3239. )
  3240. );
  3241. domUtils.append($content, $useRegExp);
  3242. });
  3243. domUtils.on($refresh, "click", (event) => {
  3244. utils.preventEvent(event);
  3245. let searchText = domUtils.val($search);
  3246. if (searchText == "") {
  3247. updateCookieListGroup();
  3248. } else {
  3249. utils.dispatchEvent($search, "input");
  3250. }
  3251. });
  3252. domUtils.on($add, "click", (event) => {
  3253. utils.preventEvent(event);
  3254. CookieManagerEditView.showView(void 0, (__cookieInfo__) => {
  3255. updateCookieListGroup();
  3256. });
  3257. });
  3258. domUtils.on($copyAll, "click", (event) => {
  3259. utils.preventEvent(event);
  3260. CookieManager.queryAllCookie().then((cookieList) => {
  3261. cookieList = cookieList.filter((it) => {
  3262. return !(it.session && PopsPanel.getValue("exclude-session-cookie"));
  3263. });
  3264. if (cookieList.length === 0) {
  3265. Qmsg.warning("没有Cookie可以复制");
  3266. return;
  3267. }
  3268. let cookieText = cookieList.map((it) => {
  3269. let cookieItemValueText = it.value;
  3270. return `${it.name}=${cookieItemValueText}; `;
  3271. }).join("");
  3272. utils.setClip(cookieText).then((status) => {
  3273. if (status) {
  3274. Qmsg.success("复制成功");
  3275. } else {
  3276. Qmsg.error("复制失败");
  3277. }
  3278. });
  3279. });
  3280. });
  3281. domUtils.on($clearAll, "click", (event) => {
  3282. utils.preventEvent(event);
  3283. let result = window.confirm("确定清除全部Cookie?");
  3284. if (!result) {
  3285. return;
  3286. }
  3287. CookieManager.deleteAllCookie().then((deleteInfo) => {
  3288. if (deleteInfo.error) {
  3289. Qmsg.warning(
  3290. `清除成功:${deleteInfo.success} 失败:${deleteInfo.error}`
  3291. );
  3292. } else {
  3293. Qmsg.success("清除成功");
  3294. }
  3295. updateCookieListGroup();
  3296. });
  3297. });
  3298. domUtils.on($ruleManager, "click", (event) => {
  3299. utils.preventEvent(event);
  3300. CookieRule.showView();
  3301. });
  3302. domUtils.on($setting, "click", (event) => {
  3303. utils.preventEvent(event);
  3304. let $settingAlert = __pops.alert({
  3305. title: {
  3306. text: "设置",
  3307. position: "center"
  3308. },
  3309. content: {
  3310. text: "",
  3311. html: true
  3312. },
  3313. btn: {
  3314. ok: {
  3315. enable: false
  3316. }
  3317. },
  3318. drag: true,
  3319. mask: {
  3320. clickEvent: {
  3321. toClose: true
  3322. }
  3323. },
  3324. width: PanelUISize.info.width,
  3325. height: PanelUISize.info.height,
  3326. style: (
  3327. /*css*/
  3328. `
  3329. ${__pops.config.cssText.panelCSS}
  3330.  
  3331. .pops-alert-content li{
  3332. display: flex;
  3333. justify-content: space-between;
  3334. align-items: center;
  3335. padding: 10px;
  3336. }
  3337. .pops-panel-item-left-desc-text{
  3338. line-height: normal;
  3339. margin-top: 6px;
  3340. font-size: 0.8em;
  3341. color: rgb(108, 108, 108);
  3342. }
  3343. `
  3344. )
  3345. });
  3346. let $content = $settingAlert.$shadowRoot.querySelector(
  3347. ".pops-alert-content"
  3348. );
  3349. let panelHandleContentUtils = __pops.config.panelHandleContentUtils();
  3350. let $useGM_cookie = panelHandleContentUtils.createSectionContainerItem_select(
  3351. UISelect(
  3352. "CookieManager Api",
  3353. "cookie-manager-api",
  3354. "document.cookie",
  3355. [
  3356. {
  3357. text: "document.cookie",
  3358. value: "document.cookie"
  3359. },
  3360. {
  3361. text: "cookieStore",
  3362. value: "cookieStore"
  3363. },
  3364. {
  3365. text: "GM_cookie",
  3366. value: "GM_cookie"
  3367. }
  3368. ],
  3369. () => {
  3370. updateCookieListGroup();
  3371. },
  3372. "操作Cookie的Api函数"
  3373. )
  3374. );
  3375. let $decodeValue = panelHandleContentUtils.createSectionContainerItem_switch(
  3376. UISwitch(
  3377. "解码Cookie值",
  3378. "decode-cookie-value",
  3379. false,
  3380. () => {
  3381. updateCookieListGroup();
  3382. },
  3383. "对Cookie值进行解码"
  3384. )
  3385. );
  3386. let $excludeSessionCookie = panelHandleContentUtils.createSectionContainerItem_switch(
  3387. UISwitch(
  3388. "排除Session Cookie",
  3389. "exclude-session-cookie",
  3390. false,
  3391. () => {
  3392. updateCookieListGroup();
  3393. },
  3394. "过滤掉浏览器会话Cookie"
  3395. )
  3396. );
  3397. domUtils.append($content, [
  3398. $useGM_cookie,
  3399. $decodeValue,
  3400. $excludeSessionCookie
  3401. ]);
  3402. });
  3403. },
  3404. /**
  3405. * 注册脚本菜单
  3406. */
  3407. registerMenu() {
  3408. const that = this;
  3409. GM_Menu.add({
  3410. key: "cookie_manager_view",
  3411. text: "⚙ Cookie管理",
  3412. autoReload: false,
  3413. isStoreValue: false,
  3414. showText(text, enable) {
  3415. return text;
  3416. },
  3417. callback(data) {
  3418. that.showView();
  3419. }
  3420. });
  3421. }
  3422. };
  3423. const CookieRuleController = {
  3424. init() {
  3425. this.execController();
  3426. domUtils.ready(() => {
  3427. this.execController();
  3428. });
  3429. },
  3430. /**
  3431. * 执行操作
  3432. */
  3433. execController() {
  3434. for (let index = 0; index < CookieRule.$data.ruleData.length; index++) {
  3435. const rule = CookieRule.$data.ruleData[index];
  3436. CookieManager.queryAllCookie().then(async (cookieListResult) => {
  3437. for (let cookieInfoIndex = 0; cookieInfoIndex < cookieListResult.length; cookieInfoIndex++) {
  3438. let cookieInfo = cookieListResult[cookieInfoIndex];
  3439. const cookieName = cookieInfo.name;
  3440. const ruleCookieName = rule.data.cookieName;
  3441. let flag = false;
  3442. if (rule.data.enableRegExpToMatchCookieName) {
  3443. let regExpCookieName = new RegExp(ruleCookieName, "i");
  3444. if (regExpCookieName.test(cookieName)) {
  3445. flag = true;
  3446. }
  3447. } else {
  3448. if (cookieName.includes(ruleCookieName)) {
  3449. flag = true;
  3450. }
  3451. }
  3452. if (flag) {
  3453. let operationMode = rule.data.operationMode;
  3454. if (operationMode === "delete") {
  3455. CookieManager.deleteCookie(cookieInfo);
  3456. } else if (operationMode === "extended" || operationMode === "extended-90" || operationMode === "extended-180" || operationMode === "extended-360") {
  3457. let currentTime = Date.now();
  3458. let oneMonth = 30 * 24 * 60 * 60 * 1e3;
  3459. let threeMonth = oneMonth * 3;
  3460. let halfAYear = oneMonth * 6;
  3461. let oneYear = oneMonth * 12;
  3462. let checkTime = oneMonth;
  3463. if (operationMode === "extended-90") {
  3464. checkTime = threeMonth;
  3465. } else if (operationMode === "extended-180") {
  3466. checkTime = halfAYear;
  3467. } else if (operationMode === "extended-360") {
  3468. checkTime = oneYear;
  3469. }
  3470. let updateFlag = false;
  3471. if (CookieManager.cookieManagerApiName === "document.cookie") {
  3472. cookieInfo.expirationDate = currentTime + checkTime;
  3473. updateFlag = true;
  3474. } else if (CookieManager.cookieManagerApiName === "cookieStore") {
  3475. let expireTime = cookieInfo.expires;
  3476. if (typeof expireTime === "number" && expireTime - currentTime < checkTime) {
  3477. cookieInfo.expires = expireTime + checkTime;
  3478. updateFlag = true;
  3479. }
  3480. } else if (CookieManager.cookieManagerApiName === "GM_cookie") {
  3481. let expireTime = cookieInfo.expirationDate;
  3482. if (typeof expireTime === "number" && expireTime * 1e3 - currentTime < checkTime) {
  3483. cookieInfo.expirationDate = expireTime + checkTime / 1e3;
  3484. updateFlag = true;
  3485. }
  3486. } else {
  3487. log.error(
  3488. "未知的cookieManagerApiName",
  3489. CookieManager.cookieManagerApiName
  3490. );
  3491. }
  3492. if (updateFlag) {
  3493. await CookieManager.updateCookie(cookieInfo);
  3494. }
  3495. }
  3496. }
  3497. }
  3498. });
  3499. }
  3500. }
  3501. };
  3502. PopsPanel.init();
  3503. CookieRule.init();
  3504. CookieRuleController.init();
  3505. CookieManagerView.init();
  3506.  
  3507. })(Qmsg, DOMUtils, Utils, pops);