a2bei4-utils 1.0.6 → 1.0.8
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/dist/a2bei4.utils.cjs.js +168 -1
- package/dist/a2bei4.utils.cjs.js.map +1 -1
- package/dist/a2bei4.utils.cjs.min.js +1 -1
- package/dist/a2bei4.utils.cjs.min.js.map +1 -1
- package/dist/a2bei4.utils.esm.js +167 -2
- package/dist/a2bei4.utils.esm.js.map +1 -1
- package/dist/a2bei4.utils.esm.min.js +1 -1
- package/dist/a2bei4.utils.esm.min.js.map +1 -1
- package/dist/a2bei4.utils.umd.js +168 -1
- package/dist/a2bei4.utils.umd.js.map +1 -1
- package/dist/a2bei4.utils.umd.min.js +1 -1
- package/dist/a2bei4.utils.umd.min.js.map +1 -1
- package/dist/browser.cjs +106 -1
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +106 -2
- package/dist/browser.js.map +1 -1
- package/dist/download.cjs +3 -0
- package/dist/download.cjs.map +1 -1
- package/dist/download.js +3 -0
- package/dist/download.js.map +1 -1
- package/dist/tree.cjs +59 -0
- package/dist/tree.cjs.map +1 -1
- package/dist/tree.js +59 -1
- package/dist/tree.js.map +1 -1
- package/package.json +1 -1
- package/types/browser.d.ts +10 -1
- package/types/index.d.ts +32 -1
- package/types/tree.d.ts +23 -1
package/dist/a2bei4.utils.umd.js
CHANGED
|
@@ -361,7 +361,111 @@ registerProcessor('audio-stream-resampler-processor', AudioStreamResamplerProces
|
|
|
361
361
|
function getSearchParam(key) {
|
|
362
362
|
const params = getAllSearchParams();
|
|
363
363
|
return params[key];
|
|
364
|
-
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* 全屏操作辅助工具对象
|
|
368
|
+
* @namespace fullscreenHelper
|
|
369
|
+
*/
|
|
370
|
+
const fullscreenHelper = {
|
|
371
|
+
/**
|
|
372
|
+
* 请求进入全屏模式
|
|
373
|
+
* @param {Element} element - 要全屏显示的元素
|
|
374
|
+
* @returns {Promise<void> | undefined} 全屏请求 Promise(如支持)
|
|
375
|
+
*/
|
|
376
|
+
requestFullscreen: (element) => {
|
|
377
|
+
if (!element) {
|
|
378
|
+
console.warn("未提供有效的 DOM 元素");
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (element.requestFullscreen) {
|
|
382
|
+
return element.requestFullscreen();
|
|
383
|
+
} else if (element.mozRequestFullScreen) {
|
|
384
|
+
return element.mozRequestFullScreen();
|
|
385
|
+
} else if (element.webkitRequestFullscreen) {
|
|
386
|
+
return element.webkitRequestFullscreen();
|
|
387
|
+
} else if (element.msRequestFullscreen) {
|
|
388
|
+
return element.msRequestFullscreen();
|
|
389
|
+
} else {
|
|
390
|
+
console.warn("当前浏览器不支持全屏 API");
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* 退出全屏模式
|
|
396
|
+
* @returns {Promise<void> | undefined} 退出全屏请求 Promise(如支持)
|
|
397
|
+
*/
|
|
398
|
+
exitFullscreen: () => {
|
|
399
|
+
if (document.exitFullscreen) {
|
|
400
|
+
return document.exitFullscreen();
|
|
401
|
+
} else if (document.mozCancelFullScreen) {
|
|
402
|
+
return document.mozCancelFullScreen();
|
|
403
|
+
} else if (document.webkitExitFullscreen) {
|
|
404
|
+
return document.webkitExitFullscreen();
|
|
405
|
+
} else if (document.msExitFullscreen) {
|
|
406
|
+
return document.msExitFullscreen();
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* 获取当前全屏元素
|
|
412
|
+
* @returns {Element | null} 当前处于全屏模式的元素,无则返回 null
|
|
413
|
+
*/
|
|
414
|
+
getFullscreenElement: () => {
|
|
415
|
+
return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement || null;
|
|
416
|
+
},
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* 检测当前是否处于全屏模式
|
|
420
|
+
* @returns {boolean} 是否全屏中
|
|
421
|
+
*/
|
|
422
|
+
isFullscreen: () => {
|
|
423
|
+
return !!(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement);
|
|
424
|
+
},
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* 检测浏览器是否支持全屏 API
|
|
428
|
+
* @returns {boolean} 是否支持全屏
|
|
429
|
+
*/
|
|
430
|
+
isFullscreenEnabled: () => {
|
|
431
|
+
return !!(document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled || document.msFullscreenEnabled);
|
|
432
|
+
},
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* 切换指定元素的全屏状态
|
|
436
|
+
* @param {Element} element - 要切换全屏的元素
|
|
437
|
+
* @returns {Promise<void> | undefined} 全屏操作 Promise
|
|
438
|
+
*/
|
|
439
|
+
toggleFullscreen: (element) => {
|
|
440
|
+
if (fullscreenHelper.isFullscreen()) {
|
|
441
|
+
return fullscreenHelper.exitFullscreen();
|
|
442
|
+
} else {
|
|
443
|
+
return fullscreenHelper.requestFullscreen(element);
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* 监听全屏变化事件
|
|
449
|
+
* @param {Function} callback - 全屏状态变化时的回调函数,参数为 isFullscreen: boolean
|
|
450
|
+
* @returns {Function} 取消监听的函数
|
|
451
|
+
*/
|
|
452
|
+
onFullscreenChange: (callback) => {
|
|
453
|
+
const handler = () => {
|
|
454
|
+
callback(fullscreenHelper.isFullscreen());
|
|
455
|
+
};
|
|
456
|
+
document.addEventListener("fullscreenchange", handler);
|
|
457
|
+
document.addEventListener("webkitfullscreenchange", handler);
|
|
458
|
+
document.addEventListener("mozfullscreenchange", handler);
|
|
459
|
+
document.addEventListener("msfullscreenchange", handler);
|
|
460
|
+
|
|
461
|
+
return () => {
|
|
462
|
+
document.removeEventListener("fullscreenchange", handler);
|
|
463
|
+
document.removeEventListener("webkitfullscreenchange", handler);
|
|
464
|
+
document.removeEventListener("mozfullscreenchange", handler);
|
|
465
|
+
document.removeEventListener("msfullscreenchange", handler);
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
};
|
|
365
469
|
|
|
366
470
|
//#region 数据类型判断
|
|
367
471
|
|
|
@@ -1228,6 +1332,9 @@ registerProcessor('audio-stream-resampler-processor', AudioStreamResamplerProces
|
|
|
1228
1332
|
const urlPathname = new URL(url).pathname;
|
|
1229
1333
|
// 获取路径的最后一部分作为文件名,并移除可能的查询参数
|
|
1230
1334
|
fileName = urlPathname.substring(urlPathname.lastIndexOf("/") + 1).split("?")[0];
|
|
1335
|
+
if (fileName) {
|
|
1336
|
+
fileName = decodeURIComponent(fileName);
|
|
1337
|
+
}
|
|
1231
1338
|
} catch (e) {}
|
|
1232
1339
|
// 如果提取后文件名为空(例如 URL 以 '/' 结尾),也使用时间戳
|
|
1233
1340
|
if (!fileName) {
|
|
@@ -1903,6 +2010,64 @@ registerProcessor('audio-stream-resampler-processor', AudioStreamResamplerProces
|
|
|
1903
2010
|
checked: [...checked],
|
|
1904
2011
|
halfChecked: [...halfChecked]
|
|
1905
2012
|
};
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
/**
|
|
2016
|
+
* 在树形结构中查找目标节点的完整路径(从根节点到目标节点,含目标节点自身)。
|
|
2017
|
+
*
|
|
2018
|
+
* @template T extends Record<PropertyKey, any>
|
|
2019
|
+
* @param {T[]} nodes - 树形结构森林(支持多根)
|
|
2020
|
+
* @param {any} targetValue - 目标节点的 key 值
|
|
2021
|
+
* @param {string} [key='id'] - 节点唯一标识字段
|
|
2022
|
+
* @param {string} [parentKey='pid'] - 父节点标识字段(指向父节点的 key 值)
|
|
2023
|
+
* @param {string} [childrenKey='children'] - 子节点数组字段
|
|
2024
|
+
* @returns {T[]} 从根到目标节点的路径数组;未找到返回空数组
|
|
2025
|
+
*
|
|
2026
|
+
* @example
|
|
2027
|
+
* const tree = [
|
|
2028
|
+
* { id: 1, pid: null, children: [
|
|
2029
|
+
* { id: 2, pid: 1, children: [
|
|
2030
|
+
* { id: 3, pid: 2 }
|
|
2031
|
+
* ]}
|
|
2032
|
+
* ]}
|
|
2033
|
+
* ];
|
|
2034
|
+
* findTreeNodePath(tree, 3); // [{id:1, ...}, {id:2, ...}, {id:3, ...}]
|
|
2035
|
+
*/
|
|
2036
|
+
function findTreeNodePath(nodes, targetValue, key = "id", parentKey = "pid", childrenKey = "children") {
|
|
2037
|
+
if (!Array.isArray(nodes) || nodes.length === 0 || targetValue == null) {
|
|
2038
|
+
return [];
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
// 1. 建立节点索引
|
|
2042
|
+
const index = new Map();
|
|
2043
|
+
const stack = [...nodes];
|
|
2044
|
+
|
|
2045
|
+
while (stack.length) {
|
|
2046
|
+
const node = stack.pop();
|
|
2047
|
+
if (!node || typeof node !== "object") continue;
|
|
2048
|
+
|
|
2049
|
+
index.set(node[key], node);
|
|
2050
|
+
|
|
2051
|
+
const children = node[childrenKey];
|
|
2052
|
+
if (Array.isArray(children)) {
|
|
2053
|
+
stack.push(...children);
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
// 2. 回溯路径(防循环引用)
|
|
2058
|
+
const path = [];
|
|
2059
|
+
const visited = new Set();
|
|
2060
|
+
let cur = index.get(targetValue);
|
|
2061
|
+
|
|
2062
|
+
while (cur && !visited.has(cur[key])) {
|
|
2063
|
+
visited.add(cur[key]);
|
|
2064
|
+
path.push(cur);
|
|
2065
|
+
|
|
2066
|
+
const parentValue = cur[parentKey];
|
|
2067
|
+
cur = parentValue != null ? index.get(parentValue) : undefined;
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
return path.reverse();
|
|
1906
2071
|
}
|
|
1907
2072
|
|
|
1908
2073
|
/**
|
|
@@ -2328,8 +2493,10 @@ registerProcessor('audio-stream-resampler-processor', AudioStreamResamplerProces
|
|
|
2328
2493
|
exports.fetchOrDownloadByUrl = fetchOrDownloadByUrl;
|
|
2329
2494
|
exports.findObjAttrValueById = findObjAttrValueById;
|
|
2330
2495
|
exports.findTreeNodeById = findTreeNodeById;
|
|
2496
|
+
exports.findTreeNodePath = findTreeNodePath;
|
|
2331
2497
|
exports.flatCompleteTree2NestedTree = flatCompleteTree2NestedTree;
|
|
2332
2498
|
exports.formatTimeForLocale = formatTimeForLocale;
|
|
2499
|
+
exports.fullscreenHelper = fullscreenHelper;
|
|
2333
2500
|
exports.getAllSearchParams = getAllSearchParams;
|
|
2334
2501
|
exports.getDataType = getDataType;
|
|
2335
2502
|
exports.getFunctionArgNames = getFunctionArgNames;
|