sculp-js 1.7.2 → 1.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.
- package/README.md +5 -3
- package/lib/cjs/array.js +6 -4
- package/lib/cjs/async.js +1 -1
- package/lib/cjs/base64.js +1 -1
- package/lib/cjs/clipboard.js +1 -1
- package/lib/cjs/cookie.js +1 -1
- package/lib/cjs/date.js +1 -1
- package/lib/cjs/dom.js +1 -28
- package/lib/cjs/download.js +1 -1
- package/lib/cjs/easing.js +1 -1
- package/lib/cjs/file.js +1 -1
- package/lib/cjs/func.js +1 -1
- package/lib/cjs/index.js +3 -4
- package/lib/cjs/math.js +1 -1
- package/lib/cjs/number.js +1 -1
- package/lib/cjs/object.js +133 -4
- package/lib/cjs/path.js +3 -3
- package/lib/cjs/qs.js +1 -1
- package/lib/cjs/random.js +1 -1
- package/lib/cjs/string.js +1 -1
- package/lib/cjs/tooltip.js +1 -1
- package/lib/cjs/tree.js +12 -96
- package/lib/cjs/type.js +11 -4
- package/lib/cjs/unique.js +1 -1
- package/lib/cjs/url.js +1 -1
- package/lib/cjs/validator.js +1 -1
- package/lib/cjs/variable.js +1 -1
- package/lib/cjs/watermark.js +1 -1
- package/lib/cjs/we-decode.js +7 -6
- package/lib/es/array.js +6 -4
- package/lib/es/async.js +1 -1
- package/lib/es/base64.js +1 -1
- package/lib/es/clipboard.js +1 -1
- package/lib/es/cookie.js +1 -1
- package/lib/es/date.js +1 -1
- package/lib/es/dom.js +2 -27
- package/lib/es/download.js +1 -1
- package/lib/es/easing.js +1 -1
- package/lib/es/file.js +1 -1
- package/lib/es/func.js +1 -1
- package/lib/es/index.js +5 -5
- package/lib/es/math.js +1 -1
- package/lib/es/number.js +1 -1
- package/lib/es/object.js +133 -5
- package/lib/es/path.js +3 -3
- package/lib/es/qs.js +1 -1
- package/lib/es/random.js +1 -1
- package/lib/es/string.js +1 -1
- package/lib/es/tooltip.js +1 -1
- package/lib/es/tree.js +13 -96
- package/lib/es/type.js +11 -5
- package/lib/es/unique.js +1 -1
- package/lib/es/url.js +1 -1
- package/lib/es/validator.js +1 -1
- package/lib/es/variable.js +1 -1
- package/lib/es/watermark.js +1 -1
- package/lib/es/we-decode.js +7 -6
- package/lib/index.d.ts +27 -49
- package/lib/umd/index.js +166 -139
- package/package.json +3 -10
package/lib/umd/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
2
|
+
* sculp-js v1.8.1
|
|
3
3
|
* (c) 2023-present chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
|
-
for (let idx = 0
|
|
33
|
+
for (let idx = 0, len = array.length; idx < len; idx++) {
|
|
34
34
|
const val = array[idx];
|
|
35
35
|
const re = iterator(val, idx, array);
|
|
36
36
|
if (re === false)
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
|
-
for (let idx = 0
|
|
58
|
+
for (let idx = 0, len = array.length; idx < len; idx++) {
|
|
59
59
|
const val = array[idx];
|
|
60
60
|
if ((await iterator(val, idx)) === false)
|
|
61
61
|
break;
|
|
@@ -92,7 +92,9 @@
|
|
|
92
92
|
if (_expect(val, idx))
|
|
93
93
|
indexes.push(idx);
|
|
94
94
|
});
|
|
95
|
-
indexes
|
|
95
|
+
arrayEach(indexes, (val, idx) => {
|
|
96
|
+
array.splice(val - idx, 1);
|
|
97
|
+
});
|
|
96
98
|
return array;
|
|
97
99
|
}
|
|
98
100
|
|
|
@@ -122,11 +124,17 @@
|
|
|
122
124
|
return objectHas(any, 'length');
|
|
123
125
|
}
|
|
124
126
|
/**
|
|
125
|
-
*
|
|
127
|
+
* 判断任意值的数据类型,检查非对象时不如typeof、instanceof的性能高
|
|
128
|
+
*
|
|
129
|
+
* 当检查类对象时是不可靠的,对象可以通过定义 Symbol.toStringTag 属性来更改检查结果
|
|
130
|
+
*
|
|
131
|
+
* 详见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
|
|
126
132
|
* @param {unknown} any
|
|
127
|
-
* @returns
|
|
133
|
+
* @returns
|
|
128
134
|
*/
|
|
129
|
-
|
|
135
|
+
function typeIs(any) {
|
|
136
|
+
return Object.prototype.toString.call(any).slice(8, -1);
|
|
137
|
+
}
|
|
130
138
|
// 基本数据类型判断
|
|
131
139
|
const isString = (any) => typeof any === 'string';
|
|
132
140
|
const isBoolean = (any) => typeof any === 'boolean';
|
|
@@ -369,7 +377,7 @@
|
|
|
369
377
|
*/
|
|
370
378
|
function objectAssign(source, ...targets) {
|
|
371
379
|
const map = new Map();
|
|
372
|
-
for (let i = 0
|
|
380
|
+
for (let i = 0, len = targets.length; i < len; i++) {
|
|
373
381
|
const target = targets[i];
|
|
374
382
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
375
383
|
// @ts-ignore
|
|
@@ -394,6 +402,13 @@
|
|
|
394
402
|
});
|
|
395
403
|
return source;
|
|
396
404
|
}
|
|
405
|
+
/**
|
|
406
|
+
* 获取对象指定层级下的属性值(现在可用ES6+的可选链?.来替代)
|
|
407
|
+
* @param {AnyObject} obj
|
|
408
|
+
* @param {string} path
|
|
409
|
+
* @param {boolean} strict
|
|
410
|
+
* @returns
|
|
411
|
+
*/
|
|
397
412
|
function objectGet(obj, path, strict = false) {
|
|
398
413
|
path = path.replace(/\[(\w+)\]/g, '.$1');
|
|
399
414
|
path = path.replace(/^\./, '');
|
|
@@ -487,10 +502,10 @@
|
|
|
487
502
|
}
|
|
488
503
|
// 处理数组 (包含稀疏数组)
|
|
489
504
|
if (Array.isArray(source)) {
|
|
490
|
-
const copy = Array
|
|
505
|
+
const copy = new Array(source.length);
|
|
491
506
|
map.set(source, copy);
|
|
492
507
|
// 克隆所有有效索引
|
|
493
|
-
for (let i = 0
|
|
508
|
+
for (let i = 0, len = source.length; i < len; i++) {
|
|
494
509
|
if (i in source) {
|
|
495
510
|
// 保留空位
|
|
496
511
|
copy[i] = cloneDeep(source[i], map);
|
|
@@ -529,6 +544,127 @@
|
|
|
529
544
|
}
|
|
530
545
|
return copy;
|
|
531
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* 比较两值是否相等,适用所有数据类型
|
|
549
|
+
* @param {Comparable} a
|
|
550
|
+
* @param {Comparable} b
|
|
551
|
+
* @returns {boolean}
|
|
552
|
+
*/
|
|
553
|
+
function isEqual(a, b) {
|
|
554
|
+
return deepEqual(a, b);
|
|
555
|
+
}
|
|
556
|
+
function deepEqual(a, b, compared = new WeakMap()) {
|
|
557
|
+
// 相同值快速返回
|
|
558
|
+
if (Object.is(a, b))
|
|
559
|
+
return true;
|
|
560
|
+
// 类型不同直接返回false
|
|
561
|
+
const typeA = Object.prototype.toString.call(a);
|
|
562
|
+
const typeB = Object.prototype.toString.call(b);
|
|
563
|
+
if (typeA !== typeB)
|
|
564
|
+
return false;
|
|
565
|
+
// 只缓存对象类型
|
|
566
|
+
if (isObject(a) && isObject(b)) {
|
|
567
|
+
if (compared.has(a))
|
|
568
|
+
return compared.get(a) === b;
|
|
569
|
+
compared.set(a, b);
|
|
570
|
+
compared.set(b, a);
|
|
571
|
+
}
|
|
572
|
+
// 处理特殊对象类型
|
|
573
|
+
switch (typeA) {
|
|
574
|
+
case '[object Date]':
|
|
575
|
+
return a.getTime() === b.getTime();
|
|
576
|
+
case '[object RegExp]':
|
|
577
|
+
return a.toString() === b.toString();
|
|
578
|
+
case '[object Map]':
|
|
579
|
+
return compareMap(a, b, compared);
|
|
580
|
+
case '[object Set]':
|
|
581
|
+
return compareSet(a, b, compared);
|
|
582
|
+
case '[object ArrayBuffer]':
|
|
583
|
+
return compareArrayBuffer(a, b);
|
|
584
|
+
case '[object DataView]':
|
|
585
|
+
return compareDataView(a, b, compared);
|
|
586
|
+
case '[object Int8Array]':
|
|
587
|
+
case '[object Uint8Array]':
|
|
588
|
+
case '[object Uint8ClampedArray]':
|
|
589
|
+
case '[object Int16Array]':
|
|
590
|
+
case '[object Uint16Array]':
|
|
591
|
+
case '[object Int32Array]':
|
|
592
|
+
case '[object Uint32Array]':
|
|
593
|
+
case '[object Float32Array]':
|
|
594
|
+
case '[object Float64Array]':
|
|
595
|
+
return compareTypedArray(a, b, compared);
|
|
596
|
+
case '[object Object]':
|
|
597
|
+
return compareObjects(a, b, compared);
|
|
598
|
+
case '[object Array]':
|
|
599
|
+
return compareArrays(a, b, compared);
|
|
600
|
+
}
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
// 辅助比较函数
|
|
604
|
+
function compareMap(a, b, compared) {
|
|
605
|
+
if (a.size !== b.size)
|
|
606
|
+
return false;
|
|
607
|
+
for (const [key, value] of a) {
|
|
608
|
+
if (!b.has(key) || !deepEqual(value, b.get(key), compared))
|
|
609
|
+
return false;
|
|
610
|
+
}
|
|
611
|
+
return true;
|
|
612
|
+
}
|
|
613
|
+
function compareSet(a, b, compared) {
|
|
614
|
+
if (a.size !== b.size)
|
|
615
|
+
return false;
|
|
616
|
+
for (const value of a) {
|
|
617
|
+
let found = false;
|
|
618
|
+
for (const bValue of b) {
|
|
619
|
+
if (deepEqual(value, bValue, compared)) {
|
|
620
|
+
found = true;
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
if (!found)
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
return true;
|
|
628
|
+
}
|
|
629
|
+
function compareArrayBuffer(a, b) {
|
|
630
|
+
if (a.byteLength !== b.byteLength)
|
|
631
|
+
return false;
|
|
632
|
+
return new DataView(a).getInt32(0) === new DataView(b).getInt32(0);
|
|
633
|
+
}
|
|
634
|
+
function compareDataView(a, b, compared) {
|
|
635
|
+
return a.byteLength === b.byteLength && deepEqual(new Uint8Array(a.buffer), new Uint8Array(b.buffer), compared);
|
|
636
|
+
}
|
|
637
|
+
function compareTypedArray(a, b, compared) {
|
|
638
|
+
return a.byteLength === b.byteLength && deepEqual(Array.from(a), Array.from(b), compared);
|
|
639
|
+
}
|
|
640
|
+
function compareObjects(a, b, compared) {
|
|
641
|
+
const keysA = Reflect.ownKeys(a);
|
|
642
|
+
const keysB = Reflect.ownKeys(b);
|
|
643
|
+
if (keysA.length !== keysB.length)
|
|
644
|
+
return false;
|
|
645
|
+
for (const key of keysA) {
|
|
646
|
+
if (!keysB.includes(key))
|
|
647
|
+
return false;
|
|
648
|
+
if (!deepEqual(a[key], b[key], compared))
|
|
649
|
+
return false;
|
|
650
|
+
}
|
|
651
|
+
// 原型链比较
|
|
652
|
+
return Object.getPrototypeOf(a) === Object.getPrototypeOf(b);
|
|
653
|
+
}
|
|
654
|
+
function compareArrays(a, b, compared) {
|
|
655
|
+
// 增加有效索引检查
|
|
656
|
+
const keysA = Object.keys(a).map(Number);
|
|
657
|
+
const keysB = Object.keys(b).map(Number);
|
|
658
|
+
if (keysA.length !== keysB.length)
|
|
659
|
+
return false;
|
|
660
|
+
// 递归比较每个元素
|
|
661
|
+
for (let i = 0, len = a.length; i < len; i++) {
|
|
662
|
+
if (!deepEqual(a[i], b[i], compared))
|
|
663
|
+
return false;
|
|
664
|
+
}
|
|
665
|
+
// 比较数组对象的其他属性
|
|
666
|
+
return compareObjects(a, b, compared);
|
|
667
|
+
}
|
|
532
668
|
|
|
533
669
|
/**
|
|
534
670
|
* 将字符串转换为驼峰格式
|
|
@@ -773,31 +909,6 @@
|
|
|
773
909
|
render();
|
|
774
910
|
});
|
|
775
911
|
}
|
|
776
|
-
const domReadyCallbacks = [];
|
|
777
|
-
const eventType = 'DOMContentLoaded';
|
|
778
|
-
const listener = () => {
|
|
779
|
-
domReadyCallbacks.forEach(callback => callback());
|
|
780
|
-
domReadyCallbacks.length = 0;
|
|
781
|
-
document.removeEventListener(eventType, listener);
|
|
782
|
-
};
|
|
783
|
-
document.addEventListener(eventType, listener);
|
|
784
|
-
let readied = false;
|
|
785
|
-
function isDomReady() {
|
|
786
|
-
if (readied)
|
|
787
|
-
return true;
|
|
788
|
-
readied = ['complete', 'loaded', 'interactive'].indexOf(document.readyState) !== -1;
|
|
789
|
-
return readied;
|
|
790
|
-
}
|
|
791
|
-
function onDomReady(callback) {
|
|
792
|
-
// document readied
|
|
793
|
-
if (isDomReady()) {
|
|
794
|
-
setTimeout(callback, 0);
|
|
795
|
-
}
|
|
796
|
-
// listen document to ready
|
|
797
|
-
else {
|
|
798
|
-
domReadyCallbacks.push(callback);
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
912
|
/**
|
|
802
913
|
* 获取元素样式属性的计算值
|
|
803
914
|
* @param {HTMLElement} el
|
|
@@ -1121,7 +1232,7 @@
|
|
|
1121
1232
|
* @returns {string}
|
|
1122
1233
|
*/
|
|
1123
1234
|
const pathNormalize = (path) => {
|
|
1124
|
-
const
|
|
1235
|
+
const slices = path
|
|
1125
1236
|
.replace(/\\/g, '/')
|
|
1126
1237
|
.replace(/\/{2,}/g, '/')
|
|
1127
1238
|
.replace(/\.{3,}/g, '..')
|
|
@@ -1146,7 +1257,7 @@
|
|
|
1146
1257
|
points.pop();
|
|
1147
1258
|
}
|
|
1148
1259
|
};
|
|
1149
|
-
|
|
1260
|
+
slices.forEach(slice => {
|
|
1150
1261
|
const isCurrent = isCurrentSlice(slice);
|
|
1151
1262
|
const isParent = isParentSlice(slice);
|
|
1152
1263
|
// 未进入实际路径
|
|
@@ -1451,7 +1562,7 @@
|
|
|
1451
1562
|
// eslint-disable-next-line
|
|
1452
1563
|
const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
|
|
1453
1564
|
/**
|
|
1454
|
-
* 字符串编码成Base64 (适用于任何环境,包括小程序)
|
|
1565
|
+
* 字符串编码成Base64, 平替浏览器的btoa, 不包含中文的处理 (适用于任何环境,包括小程序)
|
|
1455
1566
|
* @param {string} string
|
|
1456
1567
|
* @returns {string}
|
|
1457
1568
|
*/
|
|
@@ -1459,8 +1570,9 @@
|
|
|
1459
1570
|
// 同window.btoa: 字符串编码成Base64
|
|
1460
1571
|
string = String(string);
|
|
1461
1572
|
let bitmap, a, b, c, result = '', i = 0;
|
|
1462
|
-
const
|
|
1463
|
-
|
|
1573
|
+
const strLen = string.length;
|
|
1574
|
+
const rest = strLen % 3;
|
|
1575
|
+
for (; i < strLen;) {
|
|
1464
1576
|
if ((a = string.charCodeAt(i++)) > 255 || (b = string.charCodeAt(i++)) > 255 || (c = string.charCodeAt(i++)) > 255)
|
|
1465
1577
|
throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
|
|
1466
1578
|
bitmap = (a << 16) | (b << 8) | c;
|
|
@@ -1473,7 +1585,7 @@
|
|
|
1473
1585
|
return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result;
|
|
1474
1586
|
}
|
|
1475
1587
|
/**
|
|
1476
|
-
* Base64
|
|
1588
|
+
* Base64解码为原始字符串,平替浏览器的atob, 不包含中文的处理(适用于任何环境,包括小程序)
|
|
1477
1589
|
* @param {string} string
|
|
1478
1590
|
* @returns {string}
|
|
1479
1591
|
*/
|
|
@@ -1484,7 +1596,7 @@
|
|
|
1484
1596
|
throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
|
|
1485
1597
|
string += '=='.slice(2 - (string.length & 3));
|
|
1486
1598
|
let bitmap, result = '', r1, r2, i = 0;
|
|
1487
|
-
for (
|
|
1599
|
+
for (const strLen = string.length; i < strLen;) {
|
|
1488
1600
|
bitmap =
|
|
1489
1601
|
(b64.indexOf(string.charAt(i++)) << 18) |
|
|
1490
1602
|
(b64.indexOf(string.charAt(i++)) << 12) |
|
|
@@ -2251,7 +2363,7 @@
|
|
|
2251
2363
|
}
|
|
2252
2364
|
}
|
|
2253
2365
|
else {
|
|
2254
|
-
for (let i = 0
|
|
2366
|
+
for (let i = 0, len = arr.length; i < len; i++) {
|
|
2255
2367
|
if (isBreak) {
|
|
2256
2368
|
break;
|
|
2257
2369
|
}
|
|
@@ -2377,92 +2489,7 @@
|
|
|
2377
2489
|
return getIds(toFlatArray(tree));
|
|
2378
2490
|
}
|
|
2379
2491
|
/**
|
|
2380
|
-
*
|
|
2381
|
-
* @param {T} array
|
|
2382
|
-
* @param {Function} callback 迭代函数
|
|
2383
|
-
* @returns {Array}
|
|
2384
|
-
*/
|
|
2385
|
-
function flatMap(array, callback) {
|
|
2386
|
-
const result = [];
|
|
2387
|
-
array.forEach((value, index) => {
|
|
2388
|
-
result.push(...callback(value, index, array));
|
|
2389
|
-
});
|
|
2390
|
-
return result;
|
|
2391
|
-
}
|
|
2392
|
-
/**
|
|
2393
|
-
* 根据 idProp 与 parentIdProp 从对象数组中构建对应的树
|
|
2394
|
-
* 当 A[parentIdProp] === B[idProp] 时,对象A会被移动到对象B的children。
|
|
2395
|
-
* 当一个对象的 parentIdProp 不与其他对象的 idProp 字段相等时,该对象被作为树的顶层节点
|
|
2396
|
-
* @param {string} idProp 元素ID
|
|
2397
|
-
* @param {string} parentIdProp 父元素ID
|
|
2398
|
-
* @param {object[]} items 一维数组
|
|
2399
|
-
* @returns {WithChildren<T>[]} 树
|
|
2400
|
-
* @example
|
|
2401
|
-
* const array = [
|
|
2402
|
-
* { id: 'node-1', parent: 'root' },
|
|
2403
|
-
* { id: 'node-2', parent: 'root' },
|
|
2404
|
-
* { id: 'node-3', parent: 'node-2' },
|
|
2405
|
-
* { id: 'node-4', parent: 'node-2' },
|
|
2406
|
-
* { id: 'node-5', parent: 'node-4' },
|
|
2407
|
-
* ]
|
|
2408
|
-
* const tree = buildTree('id', 'parent', array)
|
|
2409
|
-
* expect(tree).toEqual([
|
|
2410
|
-
* { id: 'node-1', parent: 'root' },
|
|
2411
|
-
* {
|
|
2412
|
-
* id: 'node-2',
|
|
2413
|
-
* parent: 'root',
|
|
2414
|
-
* children: [
|
|
2415
|
-
* { id: 'node-3', parent: 'node-2' },
|
|
2416
|
-
* {
|
|
2417
|
-
* id: 'node-4',
|
|
2418
|
-
* parent: 'node-2',
|
|
2419
|
-
* children: [{ id: 'node-5', parent: 'node-4' }],
|
|
2420
|
-
* },
|
|
2421
|
-
* ],
|
|
2422
|
-
* },
|
|
2423
|
-
* ])
|
|
2424
|
-
*/
|
|
2425
|
-
function buildTree(idProp, parentIdProp, items) {
|
|
2426
|
-
const wrapperMap = new Map();
|
|
2427
|
-
const ensure = (id) => {
|
|
2428
|
-
if (wrapperMap.has(id)) {
|
|
2429
|
-
return wrapperMap.get(id);
|
|
2430
|
-
}
|
|
2431
|
-
//@ts-ignore
|
|
2432
|
-
const wrapper = { id, parent: null, item: null, children: [] };
|
|
2433
|
-
wrapperMap.set(id, wrapper);
|
|
2434
|
-
return wrapper;
|
|
2435
|
-
};
|
|
2436
|
-
for (const item of items) {
|
|
2437
|
-
const parentWrapper = ensure(item[parentIdProp]);
|
|
2438
|
-
const itemWrapper = ensure(item[idProp]);
|
|
2439
|
-
//@ts-ignore
|
|
2440
|
-
itemWrapper.parent = parentWrapper;
|
|
2441
|
-
//@ts-ignore
|
|
2442
|
-
parentWrapper.children.push(itemWrapper);
|
|
2443
|
-
//@ts-ignore
|
|
2444
|
-
itemWrapper.item = item;
|
|
2445
|
-
}
|
|
2446
|
-
const topLevelWrappers = flatMap(Array.from(wrapperMap.values()).filter(wrapper => wrapper.parent === null), wrapper => wrapper.children);
|
|
2447
|
-
return unwrapRecursively(topLevelWrappers);
|
|
2448
|
-
function unwrapRecursively(wrapperArray) {
|
|
2449
|
-
const result = [];
|
|
2450
|
-
for (const wrapper of wrapperArray) {
|
|
2451
|
-
if (wrapper.children.length === 0) {
|
|
2452
|
-
result.push(wrapper.item);
|
|
2453
|
-
}
|
|
2454
|
-
else {
|
|
2455
|
-
result.push({
|
|
2456
|
-
...wrapper.item,
|
|
2457
|
-
children: unwrapRecursively(wrapper.children)
|
|
2458
|
-
});
|
|
2459
|
-
}
|
|
2460
|
-
}
|
|
2461
|
-
return result;
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
|
-
/**
|
|
2465
|
-
* 扁平化数组转换成树(效率高于buildTree)
|
|
2492
|
+
* 扁平化数组转换成树
|
|
2466
2493
|
* @param {any[]} list
|
|
2467
2494
|
* @param {IFieldOptions} options
|
|
2468
2495
|
* @returns {any[]}
|
|
@@ -2471,10 +2498,10 @@
|
|
|
2471
2498
|
const { keyField, childField, pidField } = options;
|
|
2472
2499
|
const treeArr = [];
|
|
2473
2500
|
const sourceMap = {};
|
|
2474
|
-
list
|
|
2501
|
+
arrayEach(list, item => {
|
|
2475
2502
|
sourceMap[item[keyField]] = item;
|
|
2476
2503
|
});
|
|
2477
|
-
list
|
|
2504
|
+
arrayEach(list, item => {
|
|
2478
2505
|
const parent = sourceMap[item[pidField]];
|
|
2479
2506
|
if (parent) {
|
|
2480
2507
|
(parent[childField] || (parent[childField] = [])).push(item);
|
|
@@ -2493,7 +2520,8 @@
|
|
|
2493
2520
|
*/
|
|
2494
2521
|
function flatTree(treeList, options = defaultFieldOptions) {
|
|
2495
2522
|
const { childField, keyField, pidField } = options;
|
|
2496
|
-
|
|
2523
|
+
let res = [];
|
|
2524
|
+
arrayEach(treeList, node => {
|
|
2497
2525
|
const item = {
|
|
2498
2526
|
...node,
|
|
2499
2527
|
[childField]: [] // 清空子级
|
|
@@ -2507,8 +2535,8 @@
|
|
|
2507
2535
|
}));
|
|
2508
2536
|
res = res.concat(flatTree(children, options));
|
|
2509
2537
|
}
|
|
2510
|
-
|
|
2511
|
-
|
|
2538
|
+
});
|
|
2539
|
+
return res;
|
|
2512
2540
|
}
|
|
2513
2541
|
/**
|
|
2514
2542
|
* 模糊搜索函数,返回包含搜索字符的节点及其祖先节点, 适用于树型组件的字符过滤功能
|
|
@@ -2530,7 +2558,7 @@
|
|
|
2530
2558
|
return nodes;
|
|
2531
2559
|
}
|
|
2532
2560
|
const result = [];
|
|
2533
|
-
|
|
2561
|
+
arrayEach(nodes, node => {
|
|
2534
2562
|
// 递归检查子节点是否匹配
|
|
2535
2563
|
const matchedChildren = node[options.childField] && node[options.childField].length > 0
|
|
2536
2564
|
? fuzzySearchTree(node[options.childField] || [], filterCondition, options)
|
|
@@ -2570,7 +2598,7 @@
|
|
|
2570
2598
|
});
|
|
2571
2599
|
}
|
|
2572
2600
|
}
|
|
2573
|
-
}
|
|
2601
|
+
});
|
|
2574
2602
|
return result;
|
|
2575
2603
|
}
|
|
2576
2604
|
|
|
@@ -2943,7 +2971,6 @@
|
|
|
2943
2971
|
exports.arrayLike = arrayLike;
|
|
2944
2972
|
exports.arrayRemove = arrayRemove;
|
|
2945
2973
|
exports.asyncMap = asyncMap;
|
|
2946
|
-
exports.buildTree = buildTree;
|
|
2947
2974
|
exports.calculateDate = calculateDate;
|
|
2948
2975
|
exports.calculateDateTime = calculateDateTime;
|
|
2949
2976
|
exports.chooseLocalFile = chooseLocalFile;
|
|
@@ -2984,9 +3011,9 @@
|
|
|
2984
3011
|
exports.isBoolean = isBoolean;
|
|
2985
3012
|
exports.isDate = isDate;
|
|
2986
3013
|
exports.isDigit = isDigit;
|
|
2987
|
-
exports.isDomReady = isDomReady;
|
|
2988
3014
|
exports.isEmail = isEmail;
|
|
2989
3015
|
exports.isEmpty = isEmpty;
|
|
3016
|
+
exports.isEqual = isEqual;
|
|
2990
3017
|
exports.isError = isError;
|
|
2991
3018
|
exports.isFloat = isFloat;
|
|
2992
3019
|
exports.isFunction = isFunction;
|
|
@@ -2998,6 +3025,7 @@
|
|
|
2998
3025
|
exports.isNaN = isNaN;
|
|
2999
3026
|
exports.isNull = isNull;
|
|
3000
3027
|
exports.isNullOrUnDef = isNullOrUnDef;
|
|
3028
|
+
exports.isNullish = isNullOrUnDef;
|
|
3001
3029
|
exports.isNumber = isNumber;
|
|
3002
3030
|
exports.isNumerical = isNumerical;
|
|
3003
3031
|
exports.isObject = isObject;
|
|
@@ -3024,7 +3052,6 @@
|
|
|
3024
3052
|
exports.objectMerge = objectAssign;
|
|
3025
3053
|
exports.objectOmit = objectOmit;
|
|
3026
3054
|
exports.objectPick = objectPick;
|
|
3027
|
-
exports.onDomReady = onDomReady;
|
|
3028
3055
|
exports.once = once;
|
|
3029
3056
|
exports.parseQueryParams = parseQueryParams;
|
|
3030
3057
|
exports.parseVarFromString = parseVarFromString;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sculp-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"packageManager": "npm@8.19.2",
|
|
5
|
-
"description": "js
|
|
5
|
+
"description": "js utils library, includes function library、class library",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"prepare": "husky install",
|
|
8
8
|
"build": "rollup --bundleConfigAsCjs --config rollup.config.js",
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"release:major": "standard-version --release-as major",
|
|
20
20
|
"commit": "git-cz"
|
|
21
21
|
},
|
|
22
|
-
"author": "chendq <deqiaochen@gmail.com>",
|
|
23
22
|
"main": "lib/cjs/index.js",
|
|
24
23
|
"module": "lib/es/index.js",
|
|
25
24
|
"browser": "lib/umd/index.js",
|
|
@@ -49,8 +48,7 @@
|
|
|
49
48
|
"license": "MIT",
|
|
50
49
|
"homepage": "https://github.com/chandq/sculp-js#readme",
|
|
51
50
|
"dependencies": {
|
|
52
|
-
"bezier-easing": "^2.1.0"
|
|
53
|
-
"core-js": "^3.33.0"
|
|
51
|
+
"bezier-easing": "^2.1.0"
|
|
54
52
|
},
|
|
55
53
|
"devDependencies": {
|
|
56
54
|
"@babel/core": "^7.23.2",
|
|
@@ -89,11 +87,6 @@
|
|
|
89
87
|
"rollup-plugin-dts": "^6.1.0",
|
|
90
88
|
"rollup-plugin-subpath-externals": "^3.4.0",
|
|
91
89
|
"standard-version": "^9.5.0",
|
|
92
|
-
"stylelint": "14.16",
|
|
93
|
-
"stylelint-config-css-modules": "^4.3.0",
|
|
94
|
-
"stylelint-config-prettier": "^9.0.5",
|
|
95
|
-
"stylelint-config-standard": "^20.0.0",
|
|
96
|
-
"ts-loader": "^9.5.0",
|
|
97
90
|
"typescript": "5.0.4"
|
|
98
91
|
},
|
|
99
92
|
"config": {
|