@whitesev/pops 3.2.1 → 3.3.0

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 (127) hide show
  1. package/README.md +249 -249
  2. package/dist/index.amd.js +736 -948
  3. package/dist/index.amd.js.map +1 -1
  4. package/dist/index.amd.min.js +1 -1
  5. package/dist/index.amd.min.js.map +1 -1
  6. package/dist/index.cjs.js +736 -948
  7. package/dist/index.cjs.js.map +1 -1
  8. package/dist/index.cjs.min.js +1 -1
  9. package/dist/index.cjs.min.js.map +1 -1
  10. package/dist/index.esm.js +736 -948
  11. package/dist/index.esm.js.map +1 -1
  12. package/dist/index.esm.min.js +1 -1
  13. package/dist/index.esm.min.js.map +1 -1
  14. package/dist/index.iife.js +736 -948
  15. package/dist/index.iife.js.map +1 -1
  16. package/dist/index.iife.min.js +1 -1
  17. package/dist/index.iife.min.js.map +1 -1
  18. package/dist/index.system.js +736 -948
  19. package/dist/index.system.js.map +1 -1
  20. package/dist/index.system.min.js +1 -1
  21. package/dist/index.system.min.js.map +1 -1
  22. package/dist/index.umd.js +736 -948
  23. package/dist/index.umd.js.map +1 -1
  24. package/dist/index.umd.min.js +1 -1
  25. package/dist/index.umd.min.js.map +1 -1
  26. package/dist/types/src/PopsCore.d.ts +15 -7
  27. package/dist/types/src/components/folder/types/index.d.ts +43 -13
  28. package/dist/types/src/types/PopsDOMUtilsEventType.d.ts +313 -313
  29. package/dist/types/src/types/animation.d.ts +19 -19
  30. package/dist/types/src/types/button.d.ts +94 -94
  31. package/dist/types/src/types/components.d.ts +211 -211
  32. package/dist/types/src/types/event.d.ts +43 -43
  33. package/dist/types/src/types/global.d.ts +31 -31
  34. package/dist/types/src/types/icon.d.ts +32 -32
  35. package/dist/types/src/types/inst.d.ts +28 -28
  36. package/dist/types/src/types/main.d.ts +66 -66
  37. package/dist/types/src/types/mask.d.ts +52 -52
  38. package/dist/types/src/types/position.d.ts +60 -60
  39. package/package.json +28 -27
  40. package/src/Pops.ts +206 -206
  41. package/src/PopsAnimation.ts +32 -32
  42. package/src/PopsCSS.ts +54 -54
  43. package/src/PopsCore.ts +53 -37
  44. package/src/PopsIcon.ts +95 -95
  45. package/src/PopsInst.ts +21 -21
  46. package/src/components/alert/defaultConfig.ts +62 -62
  47. package/src/components/alert/index.ts +163 -163
  48. package/src/components/alert/types/index.ts +23 -23
  49. package/src/components/confirm/defaultConfig.ts +90 -90
  50. package/src/components/confirm/index.ts +165 -165
  51. package/src/components/confirm/types/index.ts +13 -17
  52. package/src/components/drawer/defaultConfig.ts +89 -89
  53. package/src/components/drawer/index.css +37 -37
  54. package/src/components/drawer/index.ts +245 -245
  55. package/src/components/drawer/types/index.ts +62 -61
  56. package/src/components/folder/defaultConfig.ts +151 -151
  57. package/src/components/folder/folderIcon.ts +28 -28
  58. package/src/components/folder/index.css +303 -303
  59. package/src/components/folder/index.ts +953 -932
  60. package/src/components/folder/types/index.ts +143 -110
  61. package/src/components/iframe/defaultConfig.ts +60 -60
  62. package/src/components/iframe/index.css +76 -76
  63. package/src/components/iframe/index.ts +331 -331
  64. package/src/components/iframe/types/index.ts +96 -96
  65. package/src/components/loading/defaultConfig.ts +29 -29
  66. package/src/components/loading/index.css +66 -66
  67. package/src/components/loading/index.ts +101 -101
  68. package/src/components/loading/types/index.ts +36 -34
  69. package/src/components/panel/css/components-select.css +84 -84
  70. package/src/components/panel/defaultConfig.ts +868 -868
  71. package/src/components/panel/handlerComponents.ts +3993 -3993
  72. package/src/components/panel/index.css +1403 -1403
  73. package/src/components/panel/index.ts +221 -221
  74. package/src/components/panel/types/components-button.ts +56 -56
  75. package/src/components/panel/types/components-common.ts +73 -73
  76. package/src/components/panel/types/components-container.ts +25 -25
  77. package/src/components/panel/types/components-deepMenu.ts +64 -64
  78. package/src/components/panel/types/components-input.ts +90 -90
  79. package/src/components/panel/types/components-own.ts +16 -16
  80. package/src/components/panel/types/components-select.ts +169 -169
  81. package/src/components/panel/types/components-selectMultiple.ts +105 -104
  82. package/src/components/panel/types/components-slider.ts +55 -55
  83. package/src/components/panel/types/components-switch.ts +33 -33
  84. package/src/components/panel/types/components-textarea.ts +45 -45
  85. package/src/components/panel/types/index.ts +244 -244
  86. package/src/components/prompt/defaultConfig.ts +94 -94
  87. package/src/components/prompt/index.css +34 -34
  88. package/src/components/prompt/index.ts +187 -215
  89. package/src/components/prompt/types/index.ts +57 -56
  90. package/src/components/rightClickMenu/defaultConfig.ts +103 -103
  91. package/src/components/rightClickMenu/index.css +115 -115
  92. package/src/components/rightClickMenu/index.ts +662 -662
  93. package/src/components/rightClickMenu/types/index.ts +145 -143
  94. package/src/components/searchSuggestion/defaultConfig.ts +63 -63
  95. package/src/components/searchSuggestion/index.ts +813 -813
  96. package/src/components/searchSuggestion/types/index.ts +244 -242
  97. package/src/components/tooltip/defaultConfig.ts +33 -33
  98. package/src/components/tooltip/index.css +199 -199
  99. package/src/components/tooltip/index.ts +617 -617
  100. package/src/components/tooltip/types/index.ts +123 -121
  101. package/src/config/CommonCSSClassName.ts +17 -17
  102. package/src/config/GlobalConfig.ts +63 -63
  103. package/src/css/animation.css +987 -987
  104. package/src/css/button.css +551 -551
  105. package/src/css/common.css +54 -54
  106. package/src/css/index.css +253 -253
  107. package/src/css/ninePalaceGridPosition.css +50 -50
  108. package/src/css/scrollbar.css +22 -22
  109. package/src/handler/PopsElementHandler.ts +303 -303
  110. package/src/handler/PopsHandler.ts +611 -611
  111. package/src/types/PopsDOMUtilsEventType.d.ts +313 -313
  112. package/src/types/animation.d.ts +19 -19
  113. package/src/types/button.d.ts +94 -94
  114. package/src/types/components.d.ts +211 -211
  115. package/src/types/event.d.ts +43 -43
  116. package/src/types/global.d.ts +31 -31
  117. package/src/types/icon.d.ts +32 -32
  118. package/src/types/inst.d.ts +28 -28
  119. package/src/types/main.d.ts +66 -66
  120. package/src/types/mask.d.ts +52 -52
  121. package/src/types/position.d.ts +60 -60
  122. package/src/utils/PopsDOMUtils.ts +2483 -2483
  123. package/src/utils/PopsDOMUtilsEventsConfig.ts +4 -4
  124. package/src/utils/PopsInstanceUtils.ts +714 -714
  125. package/src/utils/PopsMathUtils.ts +71 -71
  126. package/src/utils/PopsSafeUtils.ts +22 -22
  127. package/src/utils/PopsUtils.ts +391 -421
@@ -1,421 +1,391 @@
1
- import { PopsCore } from "../PopsCore";
2
- import type { PopsUtilsOwnObject } from "../types/main";
3
- import {
4
- clearInterval as WorkerClearInterval,
5
- clearTimeout as WorkerClearTimeout,
6
- setInterval as WorkerSetInterval,
7
- setTimeout as WorkerSetTimeout,
8
- } from "worker-timers";
9
- import AnyTouch from "any-touch";
10
-
11
- class PopsUtils {
12
- /**
13
- * 判断是否是window,例如window、self、globalThis
14
- * @param target
15
- */
16
- isWin(target: any) {
17
- if (typeof target !== "object") {
18
- return false;
19
- }
20
- if (target instanceof Node) {
21
- return false;
22
- }
23
- if (target === globalThis) {
24
- return true;
25
- }
26
- if (target === window) {
27
- return true;
28
- }
29
- if (target === self) {
30
- return true;
31
- }
32
- if (target === PopsCore.globalThis) {
33
- return true;
34
- }
35
- if (target === PopsCore.window) {
36
- return true;
37
- }
38
- if (target === PopsCore.self) {
39
- return true;
40
- }
41
- if (typeof unsafeWindow !== "undefined" && target === unsafeWindow) {
42
- return true;
43
- }
44
- if (target?.Math?.toString() !== "[object Math]") {
45
- return false;
46
- }
47
- return true;
48
- }
49
- /**
50
- * 判断对象是否是元素
51
- * @param target
52
- * @returns
53
- * + true 是元素
54
- * + false 不是元素
55
- * @example
56
- * Utils.isDOM(document.querySelector("a"))
57
- * > true
58
- */
59
- isDOM(target: any): boolean;
60
- isDOM(target: any): boolean {
61
- return target instanceof Node;
62
- }
63
- /**
64
- * 删除对象上的属性
65
- * @param target
66
- * @param propName
67
- */
68
- delete(target: any, propName: any) {
69
- if (typeof Reflect === "object" && typeof Reflect.deleteProperty === "function") {
70
- Reflect.deleteProperty(target, propName);
71
- } else {
72
- delete target[propName];
73
- }
74
- }
75
- /**
76
- * JSON数据从源端替换到目标端中,如果目标端存在该数据则替换,不添加,返回结果为目标端替换完毕的结果
77
- * @param target 目标数据
78
- * @param source 源数据
79
- * @param isAdd 是否可以追加键,默认false
80
- * @example
81
- * Utils.assign({"1":1,"2":{"3":3}}, {"2":{"3":4}});
82
- * >
83
- * {
84
- "1": 1,
85
- "2": {
86
- "3": 4
87
- }
88
- }
89
- */
90
- assign<T1, T2 extends object, T3 extends boolean>(target: T1, source: T2, isAdd?: T3): T3 extends true ? T1 & T2 : T1;
91
- assign(target = {}, source = {}, isAdd = false) {
92
- const UtilsContext = this;
93
- if (Array.isArray(source)) {
94
- const canTraverse = source.filter((item) => {
95
- return typeof item === "object";
96
- });
97
- if (!canTraverse.length) {
98
- return source;
99
- }
100
- }
101
- if (source == null) {
102
- return target;
103
- }
104
- if (target == null) {
105
- target = {};
106
- }
107
- // 当前遍历的目标对象
108
- let iteratorTarget;
109
- if (isAdd) {
110
- // 追加并覆盖是以source为准
111
- iteratorTarget = source;
112
- } else {
113
- // 覆盖以target为准
114
- iteratorTarget = target;
115
- }
116
- for (const keyName in iteratorTarget) {
117
- if (!isAdd && !(keyName in source)) {
118
- // 仅替换 但是源端没有此键
119
- continue;
120
- }
121
- const targetValue = Reflect.get(target, keyName);
122
- const sourceValue = Reflect.get(source, keyName);
123
- if (
124
- typeof sourceValue === "object" &&
125
- sourceValue != null &&
126
- keyName in target &&
127
- !UtilsContext.isDOM(sourceValue)
128
- ) {
129
- // 源端的值是object类型,且不是元素节点
130
- // 如果是数组,那此数组中有值,清空旧的数组再赋值
131
- let childObjectValue;
132
- if (Array.isArray(sourceValue)) {
133
- if (Array.isArray(targetValue)) {
134
- targetValue.length = 0;
135
- }
136
- childObjectValue = sourceValue;
137
- } else {
138
- childObjectValue = UtilsContext.assign(targetValue, sourceValue, isAdd);
139
- }
140
- Reflect.set(target, keyName, childObjectValue);
141
- } else {
142
- /* 直接赋值 */
143
- Reflect.set(target, keyName, sourceValue);
144
- }
145
- }
146
-
147
- return target;
148
- }
149
- /**
150
- * 生成uuid
151
- */
152
- getRandomGUID() {
153
- if (typeof PopsCore.globalThis?.crypto?.randomUUID === "function") {
154
- return PopsCore.globalThis.crypto.randomUUID();
155
- } else {
156
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (charStr) {
157
- const randomValue = (Math.random() * 16) | 0,
158
- randomCharValue = charStr === "x" ? randomValue : (randomValue & 0x3) | 0x8;
159
- return randomCharValue.toString(16);
160
- });
161
- }
162
- }
163
- /**
164
- * 判断元素/页面中是否包含该元素
165
- * @param target 需要判断的元素
166
- * @param context 默认为body
167
- */
168
- contains(target: any): boolean;
169
- contains(context: any, target?: any): boolean;
170
- contains(...args: any[]): boolean {
171
- const [context, target] = args;
172
- if (args.length === 1) {
173
- // 只判断该页面是否存在该元素
174
- return this.contains(PopsCore.document.body || PopsCore.document.documentElement, args[0]);
175
- } else {
176
- if (target == null) {
177
- return false;
178
- }
179
- if (typeof target[Symbol.iterator] === "function") {
180
- // 可遍历的数组
181
- let flag = true;
182
- for (const targetNode of target as any) {
183
- if (!context.contains(targetNode)) {
184
- flag = false;
185
- break;
186
- }
187
- }
188
- return flag;
189
- } else {
190
- return context.contains(target);
191
- }
192
- }
193
- }
194
-
195
- /**
196
- * 获取格式化后的时间
197
- * @param text (可选)需要格式化的字符串或者时间戳,默认:new Date()
198
- * @param formatType (可选)格式化成的显示类型,默认:yyyy-MM-dd HH:mm:ss
199
- * + yyyy
200
- * + MM 月
201
- * + dd 天
202
- * + HH 时 (24小时制)
203
- * + hh 时 (12小时制)
204
- * + mm 分
205
- * + ss
206
- * @returns {string} 返回格式化后的时间
207
- * @example
208
- * Utils.formatTime("2022-08-21 23:59:00","HH:mm:ss");
209
- * > '23:59:00'
210
- * @example
211
- * Utils.formatTime(1899187424988,"HH:mm:ss");
212
- * > '15:10:13'
213
- * @example
214
- * Utils.formatTime()
215
- * > '2023-1-1 00:00:00'
216
- **/
217
- formatTime(text?: string | number | Date, formatType?: string): string;
218
- /**
219
- * 获取格式化后的时间
220
- * @param text (可选)需要格式化的字符串或者时间戳,默认:new Date()
221
- * @param formatType (可选)格式化成的显示类型,默认:yyyy-MM-dd HH:mm:ss
222
- * + yyyy
223
- * + MM 月
224
- * + dd 天
225
- * + HH 时 (24小时制)
226
- * + hh 时 (12小时制)
227
- * + mm 分
228
- * + ss
229
- * @returns {string} 返回格式化后的时间
230
- * @example
231
- * Utils.formatTime("2022-08-21 23:59:00","HH:mm:ss");
232
- * > '23:59:00'
233
- * @example
234
- * Utils.formatTime(1899187424988,"HH:mm:ss");
235
- * > '15:10:13'
236
- * @example
237
- * Utils.formatTime()
238
- * > '2023-1-1 00:00:00'
239
- **/
240
- formatTime(
241
- text?: string | number | Date,
242
- formatType?:
243
- | "yyyy-MM-dd HH:mm:ss"
244
- | "yyyy/MM/dd HH:mm:ss"
245
- | "yyyy_MM_dd_HH_mm_ss"
246
- | "yyyy年MM月dd日 HH时mm分ss秒"
247
- | "yyyyMMdd hh:mm:ss"
248
- | "yyyy年MM月dd日 HH:mm:ss"
249
- | "yyyy-MM-dd"
250
- | "yyyyMMdd"
251
- | "HH:mm:ss"
252
- ): string;
253
- formatTime(text = new Date(), formatType = "yyyy-MM-dd HH:mm:ss") {
254
- const time = text == null ? new Date() : new Date(text);
255
- /**
256
- * 校验时间补0
257
- * @param timeNum
258
- * @returns
259
- */
260
- function checkTime(timeNum: number) {
261
- if (timeNum < 10) return "0" + timeNum;
262
- return timeNum;
263
- }
264
-
265
- /**
266
- * 时间制修改 24小时制转12小时制
267
- * @param hourNum 小时
268
- * @returns
269
- */
270
- function timeSystemChange(hourNum: number) {
271
- return hourNum > 12 ? hourNum - 12 : hourNum;
272
- }
273
-
274
- const timeRegexp = {
275
- yyyy: time.getFullYear(),
276
- //
277
- MM: checkTime(time.getMonth() + 1),
278
- //
279
- dd: checkTime(time.getDate()),
280
- //
281
- HH: checkTime(time.getHours()),
282
- // 时 (24小时制)
283
- hh: checkTime(timeSystemChange(time.getHours())),
284
- // (12小时制)
285
- mm: checkTime(time.getMinutes()),
286
- //
287
- ss: checkTime(time.getSeconds()),
288
- //
289
- };
290
- Object.keys(timeRegexp).forEach(function (key) {
291
- const replaecRegexp = new RegExp(key, "g");
292
- formatType = formatType.replace(replaecRegexp, (timeRegexp as any)[key]);
293
- });
294
- return formatType;
295
- }
296
- /**
297
- * 格式化byteKB、MB、GB、TB、PB、EB、ZB、YB、BB、NB、DB
298
- * @param byteSize 字节
299
- * @param addType (可选)是否添加单位
300
- * + true (默认) 添加单位
301
- * + false 不添加单位
302
- * @returns
303
- * + {string} 当addType为true时,且保留小数点末尾2位
304
- * + {number} 当addType为false时,且保留小数点末尾2位
305
- * @example
306
- * Utils.formatByteToSize("812304");
307
- * > '793.27KB'
308
- * @example
309
- * Utils.formatByteToSize("812304",false);
310
- * > 793.27
311
- **/
312
- formatByteToSize<T extends boolean>(byteSize: number | string, addType?: T): T extends true ? string : number;
313
- formatByteToSize(byteSize: number | string, addType = true) {
314
- byteSize = parseInt(byteSize.toString());
315
- if (isNaN(byteSize)) {
316
- throw new TypeError("Utils.formatByteToSize 参数 byteSize 格式不正确");
317
- }
318
- let result = 0;
319
- let resultType = "KB";
320
- const sizeData: PopsUtilsOwnObject<number> = {};
321
- sizeData.B = 1;
322
- sizeData.KB = 1024;
323
- sizeData.MB = sizeData.KB * sizeData.KB;
324
- sizeData.GB = sizeData.MB * sizeData.KB;
325
- sizeData.TB = sizeData.GB * sizeData.KB;
326
- sizeData.PB = sizeData.TB * sizeData.KB;
327
- sizeData.EB = sizeData.PB * sizeData.KB;
328
- sizeData.ZB = sizeData.EB * sizeData.KB;
329
- sizeData.YB = sizeData.ZB * sizeData.KB;
330
- sizeData.BB = sizeData.YB * sizeData.KB;
331
- sizeData.NB = sizeData.BB * sizeData.KB;
332
- sizeData.DB = sizeData.NB * sizeData.KB;
333
- for (const key in sizeData) {
334
- result = byteSize / (sizeData as any)[key];
335
- resultType = key;
336
- if (sizeData.KB >= result) {
337
- break;
338
- }
339
- }
340
- new Date();
341
- result = result.toFixed(2) as any;
342
- result = addType ? result + resultType.toString() : (parseFloat(result.toString()) as any);
343
- return result;
344
- }
345
- AnyTouch = () => {
346
- return AnyTouch;
347
- };
348
- /**
349
- * 通过navigator.userAgent判断是否是手机访问
350
- * @param userAgent
351
- */
352
- isPhone(userAgent = PopsCore.globalThis.navigator.userAgent): boolean {
353
- return Boolean(/(iPhone|iPad|iPod|iOS|Android)/i.test(userAgent));
354
- }
355
- /**
356
- * 自动使用 Worker 执行 setTimeout
357
- */
358
- setTimeout(callback: (...args: any[]) => any, timeout: number = 0) {
359
- try {
360
- return WorkerSetTimeout(callback, timeout);
361
- } catch {
362
- return setTimeout(callback, timeout);
363
- }
364
- }
365
- /**
366
- * 配合 .setTimeout 使用
367
- */
368
- clearTimeout(timeId: number | undefined) {
369
- try {
370
- if (timeId != null) {
371
- WorkerClearTimeout(timeId);
372
- }
373
- } catch {
374
- // TODO
375
- } finally {
376
- clearTimeout(timeId);
377
- }
378
- }
379
- /**
380
- * 自动使用 Worker 执行 setInterval
381
- */
382
- setInterval(callback: (...args: any[]) => any, timeout: number = 0) {
383
- try {
384
- return WorkerSetInterval(callback, timeout);
385
- } catch {
386
- return setInterval(callback, timeout);
387
- }
388
- }
389
- /**
390
- * 配合 .setInterval 使用
391
- */
392
- clearInterval(timeId: number | undefined) {
393
- try {
394
- if (timeId != null) {
395
- WorkerClearInterval(timeId);
396
- }
397
- } catch {
398
- // 忽略
399
- } finally {
400
- clearInterval(timeId);
401
- }
402
- }
403
- /**
404
- * 覆盖对象中的数组新值
405
- */
406
- setArray<T>(target: T, key: keyof T, newArr: any[]) {
407
- if (target == null) return;
408
- if (!Array.isArray(newArr)) return;
409
- const arr: any = target[key];
410
- if (Array.isArray(target[key])) {
411
- arr.length = 0;
412
- } else {
413
- (<any>target)[key] = [];
414
- }
415
- (<any>target)[key] = newArr;
416
- }
417
- }
418
-
419
- const popsUtils = new PopsUtils();
420
-
421
- export { popsUtils };
1
+ import { PopsCore } from "../PopsCore";
2
+ import type { PopsUtilsOwnObject } from "../types/main";
3
+ import AnyTouch from "any-touch";
4
+
5
+ class PopsUtils {
6
+ /**
7
+ * 判断是否是window,例如window、self、globalThis
8
+ * @param target
9
+ */
10
+ isWin(target: any) {
11
+ if (typeof target !== "object") {
12
+ return false;
13
+ }
14
+ if (target instanceof Node) {
15
+ return false;
16
+ }
17
+ if (target === globalThis) {
18
+ return true;
19
+ }
20
+ if (target === window) {
21
+ return true;
22
+ }
23
+ if (target === self) {
24
+ return true;
25
+ }
26
+ if (target === PopsCore.globalThis) {
27
+ return true;
28
+ }
29
+ if (target === PopsCore.window) {
30
+ return true;
31
+ }
32
+ if (target === PopsCore.self) {
33
+ return true;
34
+ }
35
+ if (typeof unsafeWindow !== "undefined" && target === unsafeWindow) {
36
+ return true;
37
+ }
38
+ if (target?.Math?.toString() !== "[object Math]") {
39
+ return false;
40
+ }
41
+ return true;
42
+ }
43
+ /**
44
+ * 判断对象是否是元素
45
+ * @param target
46
+ * @returns
47
+ * + true 是元素
48
+ * + false 不是元素
49
+ * @example
50
+ * Utils.isDOM(document.querySelector("a"))
51
+ * > true
52
+ */
53
+ isDOM(target: any): boolean;
54
+ isDOM(target: any): boolean {
55
+ return target instanceof Node;
56
+ }
57
+ /**
58
+ * 删除对象上的属性
59
+ * @param target
60
+ * @param propName
61
+ */
62
+ delete(target: any, propName: any) {
63
+ if (typeof Reflect === "object" && typeof Reflect.deleteProperty === "function") {
64
+ Reflect.deleteProperty(target, propName);
65
+ } else {
66
+ delete target[propName];
67
+ }
68
+ }
69
+ /**
70
+ * JSON数据从源端替换到目标端中,如果目标端存在该数据则替换,不添加,返回结果为目标端替换完毕的结果
71
+ * @param target 目标数据
72
+ * @param source 源数据
73
+ * @param isAdd 是否可以追加键,默认false
74
+ * @example
75
+ * Utils.assign({"1":1,"2":{"3":3}}, {"2":{"3":4}});
76
+ * >
77
+ * {
78
+ "1": 1,
79
+ "2": {
80
+ "3": 4
81
+ }
82
+ }
83
+ */
84
+ assign<T1, T2 extends object, T3 extends boolean>(target: T1, source: T2, isAdd?: T3): T3 extends true ? T1 & T2 : T1;
85
+ assign(target = {}, source = {}, isAdd = false) {
86
+ const UtilsContext = this;
87
+ if (Array.isArray(source)) {
88
+ const canTraverse = source.filter((item) => {
89
+ return typeof item === "object";
90
+ });
91
+ if (!canTraverse.length) {
92
+ return source;
93
+ }
94
+ }
95
+ if (source == null) {
96
+ return target;
97
+ }
98
+ if (target == null) {
99
+ target = {};
100
+ }
101
+ // 当前遍历的目标对象
102
+ let iteratorTarget;
103
+ if (isAdd) {
104
+ // 追加并覆盖是以source为准
105
+ iteratorTarget = source;
106
+ } else {
107
+ // 覆盖以target为准
108
+ iteratorTarget = target;
109
+ }
110
+ for (const keyName in iteratorTarget) {
111
+ if (!isAdd && !(keyName in source)) {
112
+ // 仅替换 但是源端没有此键
113
+ continue;
114
+ }
115
+ const targetValue = Reflect.get(target, keyName);
116
+ const sourceValue = Reflect.get(source, keyName);
117
+ if (
118
+ typeof sourceValue === "object" &&
119
+ sourceValue != null &&
120
+ keyName in target &&
121
+ !UtilsContext.isDOM(sourceValue)
122
+ ) {
123
+ // 源端的值是object类型,且不是元素节点
124
+ // 如果是数组,那此数组中有值,清空旧的数组再赋值
125
+ let childObjectValue;
126
+ if (Array.isArray(sourceValue)) {
127
+ if (Array.isArray(targetValue)) {
128
+ targetValue.length = 0;
129
+ }
130
+ childObjectValue = sourceValue;
131
+ } else {
132
+ childObjectValue = UtilsContext.assign(targetValue, sourceValue, isAdd);
133
+ }
134
+ Reflect.set(target, keyName, childObjectValue);
135
+ } else {
136
+ /* 直接赋值 */
137
+ Reflect.set(target, keyName, sourceValue);
138
+ }
139
+ }
140
+
141
+ return target;
142
+ }
143
+ /**
144
+ * 生成uuid
145
+ */
146
+ getRandomGUID() {
147
+ if (typeof PopsCore.globalThis?.crypto?.randomUUID === "function") {
148
+ return PopsCore.globalThis.crypto.randomUUID();
149
+ } else {
150
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (charStr) {
151
+ const randomValue = (Math.random() * 16) | 0,
152
+ randomCharValue = charStr === "x" ? randomValue : (randomValue & 0x3) | 0x8;
153
+ return randomCharValue.toString(16);
154
+ });
155
+ }
156
+ }
157
+ /**
158
+ * 判断元素/页面中是否包含该元素
159
+ * @param target 需要判断的元素
160
+ * @param context 默认为body
161
+ */
162
+ contains(target: any): boolean;
163
+ contains(context: any, target?: any): boolean;
164
+ contains(...args: any[]): boolean {
165
+ const [context, target] = args;
166
+ if (args.length === 1) {
167
+ // 只判断该页面是否存在该元素
168
+ return this.contains(PopsCore.document.body || PopsCore.document.documentElement, args[0]);
169
+ } else {
170
+ if (target == null) {
171
+ return false;
172
+ }
173
+ if (typeof target[Symbol.iterator] === "function") {
174
+ // 可遍历的数组
175
+ let flag = true;
176
+ for (const targetNode of target as any) {
177
+ if (!context.contains(targetNode)) {
178
+ flag = false;
179
+ break;
180
+ }
181
+ }
182
+ return flag;
183
+ } else {
184
+ return context.contains(target);
185
+ }
186
+ }
187
+ }
188
+
189
+ /**
190
+ * 获取格式化后的时间
191
+ * @param text (可选)需要格式化的字符串或者时间戳,默认:new Date()
192
+ * @param formatType (可选)格式化成的显示类型,默认:yyyy-MM-dd HH:mm:ss
193
+ * + yyyy 年
194
+ * + MM 月
195
+ * + dd 天
196
+ * + HH 时 (24小时制)
197
+ * + hh (12小时制)
198
+ * + mm
199
+ * + ss
200
+ * @returns {string} 返回格式化后的时间
201
+ * @example
202
+ * Utils.formatTime("2022-08-21 23:59:00","HH:mm:ss");
203
+ * > '23:59:00'
204
+ * @example
205
+ * Utils.formatTime(1899187424988,"HH:mm:ss");
206
+ * > '15:10:13'
207
+ * @example
208
+ * Utils.formatTime()
209
+ * > '2023-1-1 00:00:00'
210
+ **/
211
+ formatTime(text?: string | number | Date, formatType?: string): string;
212
+ /**
213
+ * 获取格式化后的时间
214
+ * @param text (可选)需要格式化的字符串或者时间戳,默认:new Date()
215
+ * @param formatType (可选)格式化成的显示类型,默认:yyyy-MM-dd HH:mm:ss
216
+ * + yyyy 年
217
+ * + MM
218
+ * + dd 天
219
+ * + HH 时 (24小时制)
220
+ * + hh (12小时制)
221
+ * + mm
222
+ * + ss
223
+ * @returns {string} 返回格式化后的时间
224
+ * @example
225
+ * Utils.formatTime("2022-08-21 23:59:00","HH:mm:ss");
226
+ * > '23:59:00'
227
+ * @example
228
+ * Utils.formatTime(1899187424988,"HH:mm:ss");
229
+ * > '15:10:13'
230
+ * @example
231
+ * Utils.formatTime()
232
+ * > '2023-1-1 00:00:00'
233
+ **/
234
+ formatTime(
235
+ text?: string | number | Date,
236
+ formatType?:
237
+ | "yyyy-MM-dd HH:mm:ss"
238
+ | "yyyy/MM/dd HH:mm:ss"
239
+ | "yyyy_MM_dd_HH_mm_ss"
240
+ | "yyyy年MM月dd日 HH时mm分ss秒"
241
+ | "yyyy年MM月dd日 hh:mm:ss"
242
+ | "yyyy年MM月dd日 HH:mm:ss"
243
+ | "yyyy-MM-dd"
244
+ | "yyyyMMdd"
245
+ | "HH:mm:ss"
246
+ ): string;
247
+ formatTime(text = new Date(), formatType = "yyyy-MM-dd HH:mm:ss") {
248
+ const time = text == null ? new Date() : new Date(text);
249
+ /**
250
+ * 校验时间补0
251
+ * @param timeNum
252
+ * @returns
253
+ */
254
+ function checkTime(timeNum: number) {
255
+ if (timeNum < 10) return "0" + timeNum;
256
+ return timeNum;
257
+ }
258
+
259
+ /**
260
+ * 时间制修改 24小时制转12小时制
261
+ * @param hourNum 小时
262
+ * @returns
263
+ */
264
+ function timeSystemChange(hourNum: number) {
265
+ return hourNum > 12 ? hourNum - 12 : hourNum;
266
+ }
267
+
268
+ const timeRegexp = {
269
+ yyyy: time.getFullYear(),
270
+ //
271
+ MM: checkTime(time.getMonth() + 1),
272
+ // 月
273
+ dd: checkTime(time.getDate()),
274
+ //
275
+ HH: checkTime(time.getHours()),
276
+ // 时 (24小时制)
277
+ hh: checkTime(timeSystemChange(time.getHours())),
278
+ // 时 (12小时制)
279
+ mm: checkTime(time.getMinutes()),
280
+ //
281
+ ss: checkTime(time.getSeconds()),
282
+ //
283
+ };
284
+ Object.keys(timeRegexp).forEach(function (key) {
285
+ const replaecRegexp = new RegExp(key, "g");
286
+ formatType = formatType.replace(replaecRegexp, (timeRegexp as any)[key]);
287
+ });
288
+ return formatType;
289
+ }
290
+ /**
291
+ * 格式化byte为KB、MB、GB、TB、PB、EB、ZB、YB、BB、NB、DB
292
+ * @param byteSize 字节
293
+ * @param addType (可选)是否添加单位
294
+ * + true (默认) 添加单位
295
+ * + false 不添加单位
296
+ * @returns
297
+ * + {string} 当addTypetrue时,且保留小数点末尾2位
298
+ * + {number} 当addType为false时,且保留小数点末尾2位
299
+ * @example
300
+ * Utils.formatByteToSize("812304");
301
+ * > '793.27KB'
302
+ * @example
303
+ * Utils.formatByteToSize("812304",false);
304
+ * > 793.27
305
+ **/
306
+ formatByteToSize<T extends boolean>(byteSize: number | string, addType?: T): T extends true ? string : number;
307
+ formatByteToSize(byteSize: number | string, addType = true) {
308
+ byteSize = parseInt(byteSize.toString());
309
+ if (isNaN(byteSize)) {
310
+ throw new TypeError("Utils.formatByteToSize 参数 byteSize 格式不正确");
311
+ }
312
+ let result = 0;
313
+ let resultType = "KB";
314
+ const sizeData: PopsUtilsOwnObject<number> = {};
315
+ sizeData.B = 1;
316
+ sizeData.KB = 1024;
317
+ sizeData.MB = sizeData.KB * sizeData.KB;
318
+ sizeData.GB = sizeData.MB * sizeData.KB;
319
+ sizeData.TB = sizeData.GB * sizeData.KB;
320
+ sizeData.PB = sizeData.TB * sizeData.KB;
321
+ sizeData.EB = sizeData.PB * sizeData.KB;
322
+ sizeData.ZB = sizeData.EB * sizeData.KB;
323
+ sizeData.YB = sizeData.ZB * sizeData.KB;
324
+ sizeData.BB = sizeData.YB * sizeData.KB;
325
+ sizeData.NB = sizeData.BB * sizeData.KB;
326
+ sizeData.DB = sizeData.NB * sizeData.KB;
327
+ for (const key in sizeData) {
328
+ result = byteSize / (sizeData as any)[key];
329
+ resultType = key;
330
+ if (sizeData.KB >= result) {
331
+ break;
332
+ }
333
+ }
334
+ new Date();
335
+ result = result.toFixed(2) as any;
336
+ result = addType ? result + resultType.toString() : (parseFloat(result.toString()) as any);
337
+ return result;
338
+ }
339
+ AnyTouch = () => {
340
+ return AnyTouch;
341
+ };
342
+ /**
343
+ * 通过navigator.userAgent判断是否是手机访问
344
+ * @param userAgent
345
+ */
346
+ isPhone(userAgent = PopsCore.globalThis.navigator.userAgent): boolean {
347
+ return Boolean(/(iPhone|iPad|iPod|iOS|Android)/i.test(userAgent));
348
+ }
349
+ /**
350
+ * 自动使用 Worker 执行 setTimeout
351
+ */
352
+ setTimeout(callback: (...args: any[]) => any, timeout: number = 0) {
353
+ return PopsCore.setTimeout(callback, timeout);
354
+ }
355
+ /**
356
+ * 配合 .setTimeout 使用
357
+ */
358
+ clearTimeout(timeId: number | undefined) {
359
+ return PopsCore.clearTimeout(timeId);
360
+ }
361
+ /**
362
+ * 自动使用 Worker 执行 setInterval
363
+ */
364
+ setInterval(callback: (...args: any[]) => any, timeout: number = 0) {
365
+ return PopsCore.setInterval(callback, timeout);
366
+ }
367
+ /**
368
+ * 配合 .setInterval 使用
369
+ */
370
+ clearInterval(timeId: number | undefined) {
371
+ return PopsCore.clearInterval(timeId);
372
+ }
373
+ /**
374
+ * 覆盖对象中的数组新值
375
+ */
376
+ setArray<T>(target: T, key: keyof T, newArr: any[]) {
377
+ if (target == null) return;
378
+ if (!Array.isArray(newArr)) return;
379
+ const arr: any = target[key];
380
+ if (Array.isArray(target[key])) {
381
+ arr.length = 0;
382
+ } else {
383
+ (<any>target)[key] = [];
384
+ }
385
+ (<any>target)[key] = newArr;
386
+ }
387
+ }
388
+
389
+ const popsUtils = new PopsUtils();
390
+
391
+ export { popsUtils };