@whitesev/utils 2.7.8 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +176 -176
  2. package/dist/index.amd.js +896 -877
  3. package/dist/index.amd.js.map +1 -1
  4. package/dist/index.cjs.js +896 -877
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.esm.js +896 -877
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.iife.js +896 -877
  9. package/dist/index.iife.js.map +1 -1
  10. package/dist/index.system.js +896 -877
  11. package/dist/index.system.js.map +1 -1
  12. package/dist/index.umd.js +896 -877
  13. package/dist/index.umd.js.map +1 -1
  14. package/dist/types/src/CommonUtil.d.ts +59 -59
  15. package/dist/types/src/DOMUtils.d.ts +1 -1
  16. package/dist/types/src/Dictionary.d.ts +1 -1
  17. package/dist/types/src/Httpx.d.ts +2 -2
  18. package/dist/types/src/Progress.d.ts +0 -4
  19. package/dist/types/src/TryCatch.d.ts +2 -2
  20. package/dist/types/src/Utils.d.ts +365 -365
  21. package/dist/types/src/UtilsGMCookie.d.ts +2 -2
  22. package/dist/types/src/UtilsGMMenu.d.ts +1 -1
  23. package/dist/types/src/indexedDB.d.ts +3 -3
  24. package/dist/types/src/types/Event.d.ts +188 -188
  25. package/dist/types/src/types/Httpx.d.ts +1344 -1343
  26. package/dist/types/src/types/Log.d.ts +19 -19
  27. package/dist/types/src/types/Progress.d.ts +20 -20
  28. package/dist/types/src/types/React.d.ts +119 -119
  29. package/dist/types/src/types/TryCatch.d.ts +9 -9
  30. package/dist/types/src/types/UtilsGMCookie.d.ts +93 -93
  31. package/dist/types/src/types/UtilsGMMenu.d.ts +77 -77
  32. package/dist/types/src/types/Vue2.d.ts +166 -166
  33. package/dist/types/src/types/WindowApi.d.ts +14 -14
  34. package/dist/types/src/types/ajaxHooker.d.ts +151 -151
  35. package/dist/types/src/types/env.d.ts +7 -2
  36. package/dist/types/src/types/global.d.ts +31 -31
  37. package/package.json +16 -7
  38. package/src/ColorConversion.ts +105 -106
  39. package/src/CommonUtil.ts +280 -279
  40. package/src/DOMUtils.ts +251 -272
  41. package/src/Dictionary.ts +153 -154
  42. package/src/GBKEncoder.ts +108 -112
  43. package/src/Hooks.ts +73 -81
  44. package/src/Httpx.ts +1457 -1466
  45. package/src/LockFunction.ts +62 -62
  46. package/src/Log.ts +258 -259
  47. package/src/ModuleRaid.js +1 -0
  48. package/src/Progress.ts +108 -114
  49. package/src/TryCatch.ts +86 -86
  50. package/src/Utils.ts +4772 -4825
  51. package/src/UtilsCommon.ts +14 -14
  52. package/src/UtilsGMCookie.ts +254 -261
  53. package/src/UtilsGMMenu.ts +445 -454
  54. package/src/Vue.ts +233 -229
  55. package/src/WindowApi.ts +59 -59
  56. package/src/ajaxHooker/ajaxHooker.js +1 -0
  57. package/src/indexedDB.ts +497 -502
  58. package/src/types/Event.d.ts +188 -188
  59. package/src/types/Httpx.d.ts +1344 -1343
  60. package/src/types/Log.d.ts +19 -19
  61. package/src/types/Progress.d.ts +20 -20
  62. package/src/types/React.d.ts +119 -119
  63. package/src/types/TryCatch.d.ts +9 -9
  64. package/src/types/UtilsGMCookie.d.ts +93 -93
  65. package/src/types/UtilsGMMenu.d.ts +77 -77
  66. package/src/types/Vue2.d.ts +166 -166
  67. package/src/types/WindowApi.d.ts +14 -14
  68. package/src/types/ajaxHooker.d.ts +151 -151
  69. package/src/types/env.d.ts +7 -2
  70. package/src/types/global.d.ts +31 -31
@@ -1,454 +1,445 @@
1
- import { CommonUtil } from "./CommonUtil";
2
- import type {
3
- UtilsGMMenuConstructorOptions,
4
- UtilsGMMenuOption,
5
- UtilsGMMenuOptionData,
6
- } from "./types/UtilsGMMenu";
7
-
8
- export class GMMenu {
9
- private GM_Api = {
10
- /**
11
- * 获取存储的数据
12
- */
13
- getValue: null as any,
14
- /**
15
- * 设置数据到存储
16
- */
17
- setValue: null as any,
18
- /**
19
- * 注册菜单
20
- */
21
- registerMenuCommand: null as any,
22
- /**
23
- * 卸载菜单
24
- */
25
- unregisterMenuCommand: null as any,
26
- };
27
- private MenuHandle = {
28
- context: this,
29
- $data: {
30
- /**
31
- * 菜单数据
32
- */
33
- data: <UtilsGMMenuOptionData[]>[],
34
- /**
35
- * 本地存储的键名
36
- */
37
- key: "GM_Menu_Local_Map",
38
- },
39
- $default: {
40
- /** 自动刷新网页,默认为true */
41
- autoReload: true,
42
- /**
43
- * 菜单isStoreValue的默认值
44
- */
45
- isStoreValue: true,
46
- },
47
- $emoji: {
48
- /**
49
- * 菜单enable为true的emoji
50
- */
51
- success: "",
52
- /**
53
- * 菜单enable为false的emoji
54
- */
55
- error: "❌",
56
- },
57
- /**
58
- * 初始化数据
59
- */
60
- init() {
61
- for (let index = 0; index < this.$data.data.length; index++) {
62
- let menuOption = this.$data.data[index]["data"];
63
- menuOption.enable = Boolean(this.getLocalMenuData(menuOption.key, menuOption.enable as boolean));
64
- if (typeof menuOption.showText !== "function") {
65
- menuOption.showText = (menuText, menuEnable) => {
66
- if (menuEnable) {
67
- return this.$emoji.success + " " + menuText;
68
- } else {
69
- return this.$emoji.error + " " + menuText;
70
- }
71
- };
72
- }
73
- }
74
- },
75
- /**
76
- * 注册油猴菜单
77
- * @param menuOptions 如果存在,使用它
78
- */
79
- register(menuOptions?: UtilsGMMenuOptionData[]) {
80
- let that = this;
81
- if (menuOptions == null) {
82
- throw new TypeError("register菜单数据不能为空");
83
- }
84
- if (!Array.isArray(menuOptions)) {
85
- menuOptions = [menuOptions];
86
- }
87
- for (let index = 0; index < menuOptions.length; index++) {
88
- let cloneMenuOptionData = CommonUtil.deepClone(menuOptions[index].data);
89
- const { showText, clickCallBack } = this.handleMenuData(
90
- cloneMenuOptionData as Required<UtilsGMMenuOption>
91
- );
92
- let menuId = that.context.GM_Api.registerMenuCommand(showText, clickCallBack);
93
- menuOptions[index].id = menuId;
94
- (cloneMenuOptionData as any).deleteMenu = function () {
95
- that.context.GM_Api.unregisterMenuCommand(menuId);
96
- };
97
- Reflect.deleteProperty(menuOptions[index], "handleData");
98
- (menuOptions[index] as any).handleData = cloneMenuOptionData;
99
- }
100
- },
101
- /**
102
- * 获取本地存储菜单键值
103
- * @param {string} key 键
104
- */
105
- getLocalMenuData(key: string, defaultValue: boolean): boolean {
106
- let localData = this.context.GM_Api.getValue(this.$data.key, {});
107
- if (key in localData) {
108
- return (localData as any)[key];
109
- } else {
110
- return defaultValue;
111
- }
112
- },
113
- /**
114
- * 设置本地存储菜单键值
115
- * @param key
116
- * @param value 值
117
- */
118
- setLocalMenuData(key: string, value: boolean) {
119
- let localData = this.context.GM_Api.getValue(this.$data.key, {});
120
- (localData as any)[key] = value;
121
- this.context.GM_Api.setValue(this.$data.key, localData);
122
- },
123
- /**
124
- * 处理初始化配置
125
- * @param menuOption
126
- */
127
- handleInitDetail(menuOption: Required<UtilsGMMenuOption>) {
128
- menuOption.enable = Boolean(this.getLocalMenuData(menuOption.key, menuOption.enable));
129
- if (typeof menuOption.showText !== "function") {
130
- menuOption.showText = (menuText, menuEnable) => {
131
- if (menuEnable) {
132
- return this.$emoji.success + " " + menuText;
133
- } else {
134
- return this.$emoji.error + " " + menuText;
135
- }
136
- };
137
- }
138
- return menuOption;
139
- },
140
- /**
141
- * 对菜单数据进行处理
142
- * @param menuOption
143
- */
144
- handleMenuData(menuOption: Required<UtilsGMMenuOption>) {
145
- let that = this;
146
- let menuLocalDataItemKey = menuOption.key;
147
- /* 菜单默认开启的状态 */
148
- let defaultEnable = Boolean(this.getLocalMenuData(menuLocalDataItemKey, menuOption.enable));
149
- /** 油猴菜单上显示的文本 */
150
- let showText = menuOption.showText(menuOption.text, defaultEnable);
151
- // const GMMenuOptions = {
152
- // /**
153
- // * 菜单的id
154
- // */
155
- // id: menuOption.id,
156
- // /**
157
- // * 点击菜单项后是否应关闭弹出菜单
158
- // */
159
- // autoClose: menuOption.autoClose,
160
- // /**
161
- // * 菜单项的可选访问键
162
- // */
163
- // accessKey: menuOption.accessKey,
164
- // /**
165
- // * 菜单项的鼠标悬浮上的工具提示
166
- // */
167
- // title: menuOption.title,
168
- // };
169
- /* 点击菜单后触发callback后的网页是否刷新 */
170
- menuOption.autoReload =
171
- typeof menuOption.autoReload !== "boolean" ? this.$default.autoReload : menuOption.autoReload;
172
- /* 点击菜单后触发callback后的网页是否存储值 */
173
- menuOption.isStoreValue =
174
- typeof menuOption.isStoreValue !== "boolean" ? this.$default.isStoreValue : menuOption.isStoreValue;
175
- /**
176
- * 用户点击菜单后的回调函数
177
- * @param event
178
- */
179
- function clickCallBack(event: MouseEvent | PointerEvent) {
180
- let localEnable = Boolean(that.getLocalMenuData(menuLocalDataItemKey, defaultEnable));
181
- if (menuOption.isStoreValue) {
182
- that.setLocalMenuData(menuLocalDataItemKey, !localEnable);
183
- }
184
- if (typeof menuOption.callback === "function") {
185
- menuOption.callback({
186
- key: menuLocalDataItemKey,
187
- enable: !localEnable,
188
- oldEnable: localEnable,
189
- event: event,
190
- storeValue(value) {
191
- that.setLocalMenuData(menuLocalDataItemKey, value);
192
- },
193
- });
194
- }
195
- /* 不刷新网页就刷新菜单 */
196
- if (menuOption.autoReload) {
197
- window.location.reload();
198
- } else {
199
- that.context.update();
200
- }
201
- }
202
-
203
- return {
204
- showText,
205
- clickCallBack,
206
- };
207
- },
208
- /**
209
- * 获取目标菜单配置数据
210
- * @param menuKey 菜单-键key
211
- */
212
- getMenuData(menuKey: string) {
213
- return this.$data.data.find((item) => item.data.key === menuKey);
214
- },
215
- /**
216
- * 获取目标菜单配置
217
- * @param menuKey 菜单-键key
218
- */
219
- getMenuOption(menuKey: string) {
220
- return this.$data.data.find((item) => item.data.key === menuKey)?.data;
221
- },
222
- /**
223
- * 获取目标菜单处理后的配置
224
- * @param menuKey 菜单-键key
225
- */
226
- getMenuHandledOption(menuKey: string) {
227
- return this.$data.data.find((item) => item!.handleData!.key === menuKey)?.handleData;
228
- },
229
- };
230
- constructor(details: UtilsGMMenuConstructorOptions) {
231
- this.GM_Api.getValue = details.GM_getValue;
232
- this.GM_Api.setValue = details.GM_setValue;
233
- this.GM_Api.registerMenuCommand = details.GM_registerMenuCommand;
234
- this.GM_Api.unregisterMenuCommand = details.GM_unregisterMenuCommand;
235
- this.MenuHandle.$default.autoReload = typeof details.autoReload === "boolean" ? details.autoReload : true;
236
- for (const keyName of Object.keys(this.GM_Api)) {
237
- if (typeof (this.GM_Api as any)[keyName] !== "function") {
238
- throw new Error(`Utils.GM_Menu 请在脚本开头加上 @grant ${keyName},且传入该对象`);
239
- }
240
- }
241
- this.add(details?.data || []);
242
- }
243
- /**
244
- * 新增菜单数据
245
- * @param menuOption
246
- */
247
- private __add(menuOption: UtilsGMMenuOption[] | UtilsGMMenuOption) {
248
- if (Array.isArray(menuOption)) {
249
- for (let index = 0; index < menuOption.length; index++) {
250
- const option = menuOption[index];
251
- this.MenuHandle.$data.data.push({
252
- data: option,
253
- id: void 0,
254
- });
255
- }
256
- } else {
257
- this.MenuHandle.$data.data.push({
258
- data: menuOption,
259
- id: void 0,
260
- });
261
- }
262
- }
263
- /**
264
- * 新增菜单数据
265
- *
266
- * 自动调用.update()
267
- * @param menuOption
268
- */
269
- add(menuOption: UtilsGMMenuOption[] | UtilsGMMenuOption) {
270
- this.__add(menuOption);
271
- this.update();
272
- }
273
- /**
274
- * 更新菜单数据
275
- *
276
- * 实现方式:先取消注册所有已注册的菜单、再依次注册所有菜单项
277
- *
278
- * 如果菜单不存在,新增菜单项
279
- *
280
- * 如果菜单已存在,新菜单项覆盖旧的菜单项
281
- * @param options 数据
282
- */
283
- update(options?: UtilsGMMenuOption[] | UtilsGMMenuOption) {
284
- let menuOptionList: UtilsGMMenuOption[] = [];
285
- if (Array.isArray(options)) {
286
- menuOptionList = [...menuOptionList, ...options];
287
- } else if (options != null) {
288
- menuOptionList = [...menuOptionList, options];
289
- }
290
- menuOptionList.forEach((menuOption) => {
291
- let oldMenuOption = this.MenuHandle.getMenuOption(menuOption.key);
292
- if (oldMenuOption) {
293
- // 覆盖
294
- Object.assign(oldMenuOption, menuOption);
295
- } else {
296
- this.__add(menuOption);
297
- }
298
- });
299
- this.MenuHandle.$data.data.forEach((value) => {
300
- if (value.handleData) {
301
- value.handleData.deleteMenu();
302
- }
303
- });
304
- this.MenuHandle.init();
305
- this.MenuHandle.register(this.MenuHandle.$data.data);
306
- }
307
- /**
308
- * 卸载菜单
309
- * @param menuId 已注册的菜单id
310
- */
311
- delete(menuId: number) {
312
- this.GM_Api.unregisterMenuCommand(menuId);
313
- }
314
- /**
315
- * 根据键值获取enable值
316
- * @param menuKey 菜单-键key
317
- * @deprecated
318
- */
319
- get(menuKey: string): boolean {
320
- return this.getEnable(menuKey);
321
- }
322
- /**
323
- * 根据键值获取enable值
324
- * @param menuKey 菜单-键key
325
- */
326
- getEnable(menuKey: string): boolean {
327
- return this.MenuHandle.getMenuHandledOption(menuKey)!.enable as boolean;
328
- }
329
- /**
330
- * 根据键值获取text值
331
- * @param menuKey 菜单-键key
332
- */
333
- getText(menuKey: string): string {
334
- return this.MenuHandle.getMenuHandledOption(menuKey)!.text;
335
- }
336
- /**
337
- * 根据键值获取showText函数的值
338
- * @param menuKey 菜单-键key
339
- */
340
- getShowTextValue(menuKey: string): string {
341
- return this.MenuHandle.getMenuHandledOption(menuKey)!.showText(
342
- this.getText(menuKey),
343
- this.getEnable(menuKey)
344
- );
345
- }
346
- /**
347
- * 获取当前已注册菜单的id
348
- * @param menuKey
349
- */
350
- getMenuId(menuKey: string): number | undefined | null {
351
- let result = null;
352
- for (let index = 0; index < this.MenuHandle.$data.data.length; index++) {
353
- const optionData = this.MenuHandle.$data.data[index];
354
- if (optionData!.handleData!.key === menuKey) {
355
- result = optionData.id;
356
- break;
357
- }
358
- }
359
- return result;
360
- }
361
- /**
362
- * 根据键值获取accessKey值
363
- * @param menuKey 菜单-键key
364
- */
365
- getAccessKey(menuKey: string): string | undefined {
366
- return this.MenuHandle.getMenuHandledOption(menuKey)?.accessKey;
367
- }
368
- /**
369
- * 根据键值获取autoClose值
370
- * @param menuKey 菜单-键key
371
- */
372
- getAutoClose(menuKey: string): boolean | undefined {
373
- return this.MenuHandle.getMenuHandledOption(menuKey)?.autoClose;
374
- }
375
- /**
376
- * 根据键值获取autoReload值
377
- * @param menuKey 菜单-键key
378
- */
379
- getAutoReload(menuKey: string): boolean | undefined {
380
- return this.MenuHandle.getMenuHandledOption(menuKey)?.autoReload;
381
- }
382
- /**
383
- * 根据键值获取callback函数
384
- * @param menuKey 菜单-键key
385
- */
386
- getCallBack(menuKey: string): Function | undefined {
387
- return this.MenuHandle.getMenuHandledOption(menuKey)?.callback;
388
- }
389
- /**
390
- * 获取当enable为true时默认显示在菜单中前面的emoji图标
391
- */
392
- getEnableTrueEmoji() {
393
- return this.MenuHandle.$emoji.success;
394
- }
395
- /**
396
- * 获取当enable为false时默认显示在菜单中前面的emoji图标
397
- */
398
- getEnableFalseEmoji() {
399
- return this.MenuHandle.$emoji.error;
400
- }
401
- /**
402
- * 获取本地存储的菜单外部的键名
403
- * @param keyName
404
- */
405
- getLocalStorageKeyName() {
406
- return this.MenuHandle.$data.key;
407
- }
408
- /**
409
- * 设置菜单的值
410
- * @param menuKey 菜单-键key
411
- * @param value 需要设置的值
412
- */
413
- setValue(menuKey: string, value: any) {
414
- this.MenuHandle.setLocalMenuData(menuKey, value);
415
- }
416
- /**
417
- * 设置菜单的值
418
- * @param menuKey 菜单-键key
419
- * @param value 需要设置的值
420
- */
421
- setEnable(menuKey: string, value: boolean) {
422
- this.setValue(menuKey, Boolean(value));
423
- }
424
- /**
425
- * 设置当enable为true时默认显示在菜单中前面的emoji图标
426
- * @param emojiString
427
- */
428
- setEnableTrueEmoji(emojiString: string) {
429
- if (typeof emojiString !== "string") {
430
- throw new Error("参数emojiString必须是string类型");
431
- }
432
- this.MenuHandle.$emoji.success = emojiString;
433
- }
434
- /**
435
- * 设置当enable为false时默认显示在菜单中前面的emoji图标
436
- * @param emojiString
437
- */
438
- setEnableFalseEmoji(emojiString: string) {
439
- if (typeof emojiString !== "string") {
440
- throw new Error("参数emojiString必须是string类型");
441
- }
442
- this.MenuHandle.$emoji.error = emojiString;
443
- }
444
- /**
445
- * 设置本地存储的菜单外部的键名
446
- * @param keyName
447
- */
448
- setLocalStorageKeyName(keyName: string) {
449
- if (typeof keyName !== "string") {
450
- throw new Error("参数keyName必须是string类型");
451
- }
452
- this.MenuHandle.$data.key = keyName;
453
- }
454
- }
1
+ import { CommonUtil } from "./CommonUtil";
2
+ import type { UtilsGMMenuConstructorOptions, UtilsGMMenuOption, UtilsGMMenuOptionData } from "./types/UtilsGMMenu";
3
+
4
+ export class GMMenu {
5
+ private GM_Api = {
6
+ /**
7
+ * 获取存储的数据
8
+ */
9
+ getValue: null as any,
10
+ /**
11
+ * 设置数据到存储
12
+ */
13
+ setValue: null as any,
14
+ /**
15
+ * 注册菜单
16
+ */
17
+ registerMenuCommand: null as any,
18
+ /**
19
+ * 卸载菜单
20
+ */
21
+ unregisterMenuCommand: null as any,
22
+ };
23
+ private MenuHandle = {
24
+ context: this,
25
+ $data: {
26
+ /**
27
+ * 菜单数据
28
+ */
29
+ data: <UtilsGMMenuOptionData[]>[],
30
+ /**
31
+ * 本地存储的键名
32
+ */
33
+ key: "GM_Menu_Local_Map",
34
+ },
35
+ $default: {
36
+ /** 自动刷新网页,默认为true */
37
+ autoReload: true,
38
+ /**
39
+ * 菜单isStoreValue的默认值
40
+ */
41
+ isStoreValue: true,
42
+ },
43
+ $emoji: {
44
+ /**
45
+ * 菜单enable为true的emoji
46
+ */
47
+ success: "✅",
48
+ /**
49
+ * 菜单enable为false的emoji
50
+ */
51
+ error: "",
52
+ },
53
+ /**
54
+ * 初始化数据
55
+ */
56
+ init() {
57
+ for (let index = 0; index < this.$data.data.length; index++) {
58
+ const menuOption = this.$data.data[index]["data"];
59
+ menuOption.enable = Boolean(this.getLocalMenuData(menuOption.key, menuOption.enable as boolean));
60
+ if (typeof menuOption.showText !== "function") {
61
+ menuOption.showText = (menuText, menuEnable) => {
62
+ if (menuEnable) {
63
+ return `${this.$emoji.success} ${menuText}`;
64
+ } else {
65
+ return `${this.$emoji.error} ${menuText}`;
66
+ }
67
+ };
68
+ }
69
+ }
70
+ },
71
+ /**
72
+ * 注册油猴菜单
73
+ * @param menuOptions 如果存在,使用它
74
+ */
75
+ register(menuOptions?: UtilsGMMenuOptionData[]) {
76
+ const that = this;
77
+ if (menuOptions == null) {
78
+ throw new TypeError("register菜单数据不能为空");
79
+ }
80
+ if (!Array.isArray(menuOptions)) {
81
+ menuOptions = [menuOptions];
82
+ }
83
+ for (let index = 0; index < menuOptions.length; index++) {
84
+ const cloneMenuOptionData = CommonUtil.deepClone(menuOptions[index].data);
85
+ const { showText, clickCallBack } = this.handleMenuData(cloneMenuOptionData as Required<UtilsGMMenuOption>);
86
+ const menuId = that.context.GM_Api.registerMenuCommand(showText, clickCallBack);
87
+ menuOptions[index].id = menuId;
88
+ (cloneMenuOptionData as any).deleteMenu = function () {
89
+ that.context.GM_Api.unregisterMenuCommand(menuId);
90
+ };
91
+ Reflect.deleteProperty(menuOptions[index], "handleData");
92
+ (menuOptions[index] as any).handleData = cloneMenuOptionData;
93
+ }
94
+ },
95
+ /**
96
+ * 获取本地存储菜单键值
97
+ * @param {string} key 键
98
+ */
99
+ getLocalMenuData(key: string, defaultValue: boolean): boolean {
100
+ const localData = this.context.GM_Api.getValue(this.$data.key, {});
101
+ if (key in localData) {
102
+ return (localData as any)[key];
103
+ } else {
104
+ return defaultValue;
105
+ }
106
+ },
107
+ /**
108
+ * 设置本地存储菜单键值
109
+ * @param key 键
110
+ * @param value 值
111
+ */
112
+ setLocalMenuData(key: string, value: boolean) {
113
+ const localData = this.context.GM_Api.getValue(this.$data.key, {});
114
+ (localData as any)[key] = value;
115
+ this.context.GM_Api.setValue(this.$data.key, localData);
116
+ },
117
+ /**
118
+ * 处理初始化配置
119
+ * @param menuOption
120
+ */
121
+ handleInitDetail(menuOption: Required<UtilsGMMenuOption>) {
122
+ menuOption.enable = Boolean(this.getLocalMenuData(menuOption.key, menuOption.enable));
123
+ if (typeof menuOption.showText !== "function") {
124
+ menuOption.showText = (menuText, menuEnable) => {
125
+ if (menuEnable) {
126
+ return `${this.$emoji.success} ${menuText}`;
127
+ } else {
128
+ return `${this.$emoji.error} ${menuText}`;
129
+ }
130
+ };
131
+ }
132
+ return menuOption;
133
+ },
134
+ /**
135
+ * 对菜单数据进行处理
136
+ * @param menuOption
137
+ */
138
+ handleMenuData(menuOption: Required<UtilsGMMenuOption>) {
139
+ const that = this;
140
+ const menuLocalDataItemKey = menuOption.key;
141
+ /* 菜单默认开启的状态 */
142
+ const defaultEnable = Boolean(this.getLocalMenuData(menuLocalDataItemKey, menuOption.enable));
143
+ /** 油猴菜单上显示的文本 */
144
+ const showText = menuOption.showText(menuOption.text, defaultEnable);
145
+ // const GMMenuOptions = {
146
+ // /**
147
+ // * 菜单的id
148
+ // */
149
+ // id: menuOption.id,
150
+ // /**
151
+ // * 点击菜单项后是否应关闭弹出菜单
152
+ // */
153
+ // autoClose: menuOption.autoClose,
154
+ // /**
155
+ // * 菜单项的可选访问键
156
+ // */
157
+ // accessKey: menuOption.accessKey,
158
+ // /**
159
+ // * 菜单项的鼠标悬浮上的工具提示
160
+ // */
161
+ // title: menuOption.title,
162
+ // };
163
+ /* 点击菜单后触发callback后的网页是否刷新 */
164
+ menuOption.autoReload =
165
+ typeof menuOption.autoReload !== "boolean" ? this.$default.autoReload : menuOption.autoReload;
166
+ /* 点击菜单后触发callback后的网页是否存储值 */
167
+ menuOption.isStoreValue =
168
+ typeof menuOption.isStoreValue !== "boolean" ? this.$default.isStoreValue : menuOption.isStoreValue;
169
+ /**
170
+ * 用户点击菜单后的回调函数
171
+ * @param event
172
+ */
173
+ function clickCallBack(event: MouseEvent | PointerEvent) {
174
+ const localEnable = Boolean(that.getLocalMenuData(menuLocalDataItemKey, defaultEnable));
175
+ if (menuOption.isStoreValue) {
176
+ that.setLocalMenuData(menuLocalDataItemKey, !localEnable);
177
+ }
178
+ if (typeof menuOption.callback === "function") {
179
+ menuOption.callback({
180
+ key: menuLocalDataItemKey,
181
+ enable: !localEnable,
182
+ oldEnable: localEnable,
183
+ event: event,
184
+ storeValue(value) {
185
+ that.setLocalMenuData(menuLocalDataItemKey, value);
186
+ },
187
+ });
188
+ }
189
+ /* 不刷新网页就刷新菜单 */
190
+ if (menuOption.autoReload) {
191
+ window.location.reload();
192
+ } else {
193
+ that.context.update();
194
+ }
195
+ }
196
+
197
+ return {
198
+ showText,
199
+ clickCallBack,
200
+ };
201
+ },
202
+ /**
203
+ * 获取目标菜单配置数据
204
+ * @param menuKey 菜单-键key
205
+ */
206
+ getMenuData(menuKey: string) {
207
+ return this.$data.data.find((item) => item.data.key === menuKey);
208
+ },
209
+ /**
210
+ * 获取目标菜单配置
211
+ * @param menuKey 菜单-键key
212
+ */
213
+ getMenuOption(menuKey: string) {
214
+ return this.$data.data.find((item) => item.data.key === menuKey)?.data;
215
+ },
216
+ /**
217
+ * 获取目标菜单处理后的配置
218
+ * @param menuKey 菜单-键key
219
+ */
220
+ getMenuHandledOption(menuKey: string) {
221
+ return this.$data.data.find((item) => item!.handleData!.key === menuKey)?.handleData;
222
+ },
223
+ };
224
+ constructor(details: UtilsGMMenuConstructorOptions) {
225
+ this.GM_Api.getValue = details.GM_getValue;
226
+ this.GM_Api.setValue = details.GM_setValue;
227
+ this.GM_Api.registerMenuCommand = details.GM_registerMenuCommand;
228
+ this.GM_Api.unregisterMenuCommand = details.GM_unregisterMenuCommand;
229
+ this.MenuHandle.$default.autoReload = typeof details.autoReload === "boolean" ? details.autoReload : true;
230
+ for (const keyName of Object.keys(this.GM_Api)) {
231
+ if (typeof (this.GM_Api as any)[keyName] !== "function") {
232
+ throw new Error(`Utils.GM_Menu 请在脚本开头加上 @grant ${keyName},且传入该对象`);
233
+ }
234
+ }
235
+ this.add(details?.data || []);
236
+ }
237
+ /**
238
+ * 新增菜单数据
239
+ * @param menuOption
240
+ */
241
+ private __add(menuOption: UtilsGMMenuOption[] | UtilsGMMenuOption) {
242
+ if (Array.isArray(menuOption)) {
243
+ for (let index = 0; index < menuOption.length; index++) {
244
+ const option = menuOption[index];
245
+ this.MenuHandle.$data.data.push({
246
+ data: option,
247
+ id: void 0,
248
+ });
249
+ }
250
+ } else {
251
+ this.MenuHandle.$data.data.push({
252
+ data: menuOption,
253
+ id: void 0,
254
+ });
255
+ }
256
+ }
257
+ /**
258
+ * 新增菜单数据
259
+ *
260
+ * 自动调用.update()
261
+ * @param menuOption
262
+ */
263
+ add(menuOption: UtilsGMMenuOption[] | UtilsGMMenuOption) {
264
+ this.__add(menuOption);
265
+ this.update();
266
+ }
267
+ /**
268
+ * 更新菜单数据
269
+ *
270
+ * 实现方式:先取消注册所有已注册的菜单、再依次注册所有菜单项
271
+ *
272
+ * 如果菜单不存在,新增菜单项
273
+ *
274
+ * 如果菜单已存在,新菜单项覆盖旧的菜单项
275
+ * @param options 数据
276
+ */
277
+ update(options?: UtilsGMMenuOption[] | UtilsGMMenuOption) {
278
+ let menuOptionList: UtilsGMMenuOption[] = [];
279
+ if (Array.isArray(options)) {
280
+ menuOptionList = [...menuOptionList, ...options];
281
+ } else if (options != null) {
282
+ menuOptionList = [...menuOptionList, options];
283
+ }
284
+ menuOptionList.forEach((menuOption) => {
285
+ const oldMenuOption = this.MenuHandle.getMenuOption(menuOption.key);
286
+ if (oldMenuOption) {
287
+ // 覆盖
288
+ Object.assign(oldMenuOption, menuOption);
289
+ } else {
290
+ this.__add(menuOption);
291
+ }
292
+ });
293
+ this.MenuHandle.$data.data.forEach((value) => {
294
+ if (value.handleData) {
295
+ value.handleData.deleteMenu();
296
+ }
297
+ });
298
+ this.MenuHandle.init();
299
+ this.MenuHandle.register(this.MenuHandle.$data.data);
300
+ }
301
+ /**
302
+ * 卸载菜单
303
+ * @param menuId 已注册的菜单id
304
+ */
305
+ delete(menuId: number) {
306
+ this.GM_Api.unregisterMenuCommand(menuId);
307
+ }
308
+ /**
309
+ * 根据键值获取enable值
310
+ * @param menuKey 菜单-键key
311
+ * @deprecated
312
+ */
313
+ get(menuKey: string): boolean {
314
+ return this.getEnable(menuKey);
315
+ }
316
+ /**
317
+ * 根据键值获取enable值
318
+ * @param menuKey 菜单-键key
319
+ */
320
+ getEnable(menuKey: string): boolean {
321
+ return this.MenuHandle.getMenuHandledOption(menuKey)!.enable as boolean;
322
+ }
323
+ /**
324
+ * 根据键值获取text值
325
+ * @param menuKey 菜单-键key
326
+ */
327
+ getText(menuKey: string): string {
328
+ return this.MenuHandle.getMenuHandledOption(menuKey)!.text;
329
+ }
330
+ /**
331
+ * 根据键值获取showText函数的值
332
+ * @param menuKey 菜单-键key
333
+ */
334
+ getShowTextValue(menuKey: string): string {
335
+ return this.MenuHandle.getMenuHandledOption(menuKey)!.showText(this.getText(menuKey), this.getEnable(menuKey));
336
+ }
337
+ /**
338
+ * 获取当前已注册菜单的id
339
+ * @param menuKey
340
+ */
341
+ getMenuId(menuKey: string): number | undefined | null {
342
+ let result = null;
343
+ for (let index = 0; index < this.MenuHandle.$data.data.length; index++) {
344
+ const optionData = this.MenuHandle.$data.data[index];
345
+ if (optionData!.handleData!.key === menuKey) {
346
+ result = optionData.id;
347
+ break;
348
+ }
349
+ }
350
+ return result;
351
+ }
352
+ /**
353
+ * 根据键值获取accessKey值
354
+ * @param menuKey 菜单-键key
355
+ */
356
+ getAccessKey(menuKey: string): string | undefined {
357
+ return this.MenuHandle.getMenuHandledOption(menuKey)?.accessKey;
358
+ }
359
+ /**
360
+ * 根据键值获取autoClose值
361
+ * @param menuKey 菜单-键key
362
+ */
363
+ getAutoClose(menuKey: string): boolean | undefined {
364
+ return this.MenuHandle.getMenuHandledOption(menuKey)?.autoClose;
365
+ }
366
+ /**
367
+ * 根据键值获取autoReload值
368
+ * @param menuKey 菜单-键key
369
+ */
370
+ getAutoReload(menuKey: string): boolean | undefined {
371
+ return this.MenuHandle.getMenuHandledOption(menuKey)?.autoReload;
372
+ }
373
+ /**
374
+ * 根据键值获取callback函数
375
+ * @param menuKey 菜单-键key
376
+ */
377
+ getCallBack(menuKey: string): ((...args: any[]) => any) | undefined {
378
+ return this.MenuHandle.getMenuHandledOption(menuKey)?.callback;
379
+ }
380
+ /**
381
+ * 获取当enable为true时默认显示在菜单中前面的emoji图标
382
+ */
383
+ getEnableTrueEmoji() {
384
+ return this.MenuHandle.$emoji.success;
385
+ }
386
+ /**
387
+ * 获取当enable为false时默认显示在菜单中前面的emoji图标
388
+ */
389
+ getEnableFalseEmoji() {
390
+ return this.MenuHandle.$emoji.error;
391
+ }
392
+ /**
393
+ * 获取本地存储的菜单外部的键名
394
+ * @param keyName
395
+ */
396
+ getLocalStorageKeyName() {
397
+ return this.MenuHandle.$data.key;
398
+ }
399
+ /**
400
+ * 设置菜单的值
401
+ * @param menuKey 菜单-键key
402
+ * @param value 需要设置的值
403
+ */
404
+ setValue(menuKey: string, value: any) {
405
+ this.MenuHandle.setLocalMenuData(menuKey, value);
406
+ }
407
+ /**
408
+ * 设置菜单的值
409
+ * @param menuKey 菜单-键key
410
+ * @param value 需要设置的值
411
+ */
412
+ setEnable(menuKey: string, value: boolean) {
413
+ this.setValue(menuKey, Boolean(value));
414
+ }
415
+ /**
416
+ * 设置当enable为true时默认显示在菜单中前面的emoji图标
417
+ * @param emojiString
418
+ */
419
+ setEnableTrueEmoji(emojiString: string) {
420
+ if (typeof emojiString !== "string") {
421
+ throw new Error("参数emojiString必须是string类型");
422
+ }
423
+ this.MenuHandle.$emoji.success = emojiString;
424
+ }
425
+ /**
426
+ * 设置当enable为false时默认显示在菜单中前面的emoji图标
427
+ * @param emojiString
428
+ */
429
+ setEnableFalseEmoji(emojiString: string) {
430
+ if (typeof emojiString !== "string") {
431
+ throw new Error("参数emojiString必须是string类型");
432
+ }
433
+ this.MenuHandle.$emoji.error = emojiString;
434
+ }
435
+ /**
436
+ * 设置本地存储的菜单外部的键名
437
+ * @param keyName
438
+ */
439
+ setLocalStorageKeyName(keyName: string) {
440
+ if (typeof keyName !== "string") {
441
+ throw new Error("参数keyName必须是string类型");
442
+ }
443
+ this.MenuHandle.$data.key = keyName;
444
+ }
445
+ }