CookieManager

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

当前为 2025-05-18 提交的版本,查看 最新版本

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