新增功能
This commit is contained in:
+15
@@ -0,0 +1,15 @@
|
||||
export function deepClone(obj) {
|
||||
if (typeof obj !== 'object' || obj === null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
let clone = Array.isArray(obj) ? [] : {};
|
||||
|
||||
for (let key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
clone[key] = deepClone(obj[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import { isEmpty } from "./isEmpty";
|
||||
|
||||
export function findValues(obj, condition, path, results, formatResults) {
|
||||
Object.keys(obj).forEach((key) => {
|
||||
const value = obj[key];
|
||||
const currentPath = isEmpty(path) ? key : `${path}.${key}`;
|
||||
if (typeof value === 'object') {
|
||||
if (Array.isArray(value)) {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const itemPath = `${currentPath}.${i}`;
|
||||
findValues(value[i], condition, itemPath, results, formatResults);
|
||||
}
|
||||
} else {
|
||||
findValues(value, condition, currentPath, results, formatResults);
|
||||
}
|
||||
} else if (condition(value)) {
|
||||
const result = typeof formatResults === 'function' ? formatResults({ key: value, value: currentPath }) : currentPath;
|
||||
results.push(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
export * from './isEqual';
|
||||
export * from './isObject';
|
||||
export * from './toggleScreen';
|
||||
export * from './deepClone';
|
||||
export * from './uiConfig';
|
||||
export * from './findValues';
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
export function isEmpty(obj) {
|
||||
if (obj === null || obj === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof obj === 'string' && obj.trim().length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj) || typeof obj === 'object') {
|
||||
return Object.keys(obj).length === 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { isObject } from './isObject';
|
||||
|
||||
export const isEqual = (obj1, obj2) => {
|
||||
// 判断obj1或者obj2 只要有一个不是对象或者数组
|
||||
if (!isObject(obj1) || !isObject(obj2)) {
|
||||
// 值类型 (!!! 参与equal的不会是函数)
|
||||
return obj1 === obj2;
|
||||
}
|
||||
if (obj1 === obj2) {
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @description 俩个都是数组或者对象,而且不相等
|
||||
* 1. 先取出obj1,obj2的keys,比较个数
|
||||
* 2. Object.keys返回的key是放到数组中的
|
||||
* 3. 数组是以索引为key
|
||||
* 4. 对象是以属性为key
|
||||
* 5. 判断俩个对象的keys长度
|
||||
*/
|
||||
const obj1Keys = Object.keys(obj1);
|
||||
const obj2Keys = Object.keys(obj2);
|
||||
if (obj1Keys.length !== obj2Keys.length) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 以obj1 为基准,和obj2 依次递归比较
|
||||
*/
|
||||
// eslint-disable-next-line guard-for-in
|
||||
for (let key in obj1) {
|
||||
// 比较当前key的value
|
||||
const res = isEqual(obj1[key], obj2[key]);
|
||||
if (!res) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 全部相等
|
||||
*/
|
||||
return true;
|
||||
};
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export const isObject = (obj) => {
|
||||
return typeof obj === "object" && obj !== null;
|
||||
};
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
const MAX_MEMOIZE_SIZE = 500;
|
||||
|
||||
function memoize(func, resolver) {
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (typeof func !== 'function' || (resolver != null && typeof resolver !== 'function')) {
|
||||
throw new TypeError('Expected a function');
|
||||
}
|
||||
const memoized = function (...args) {
|
||||
const key = resolver ? resolver.apply(this, args) : args[0];
|
||||
const cache = memoized.cache;
|
||||
|
||||
if (cache.has(key)) {
|
||||
return cache.get(key);
|
||||
}
|
||||
const result = func.apply(this, args);
|
||||
memoized.cache = cache.set(key, result) || cache;
|
||||
return result;
|
||||
};
|
||||
memoized.cache = new (memoize.Cache || Map)();
|
||||
return memoized;
|
||||
}
|
||||
|
||||
memoize.Cache = Map;
|
||||
|
||||
function memoizeCapped(func) {
|
||||
const result = memoize(func, (key) => {
|
||||
const { cache } = result;
|
||||
if (cache.size === MAX_MEMOIZE_SIZE) {
|
||||
cache.clear();
|
||||
}
|
||||
return key;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const charCodeOfDot = '.'.charCodeAt(0);
|
||||
const reEscapeChar = /\\(\\)?/g;
|
||||
const rePropName = RegExp(
|
||||
// Match anything that isn't a dot or bracket.
|
||||
'[^.[\\]]+' + '|' +
|
||||
// Or match property names within brackets.
|
||||
'\\[(?:' +
|
||||
// Match a non-string expression.
|
||||
'([^"\'][^[]*)' + '|' +
|
||||
// Or match strings (supports escaping characters).
|
||||
'(["\'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2' +
|
||||
')\\]' + '|' +
|
||||
// Or match "" as the space between consecutive dots or empty brackets.
|
||||
'(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))'
|
||||
, 'g');
|
||||
|
||||
/**
|
||||
* Converts `string` to a property path array.
|
||||
*
|
||||
* @private
|
||||
* @param {string} string The string to convert.
|
||||
* @returns {Array} Returns the property path array.
|
||||
*/
|
||||
const stringToPath = memoizeCapped((string) => {
|
||||
const result = [];
|
||||
if (string.charCodeAt(0) === charCodeOfDot) {
|
||||
result.push('');
|
||||
}
|
||||
string.replace(rePropName, (match, expression, quote, subString) => {
|
||||
let key = match;
|
||||
if (quote) {
|
||||
key = subString.replace(reEscapeChar, '$1');
|
||||
}
|
||||
else if (expression) {
|
||||
key = expression.trim();
|
||||
}
|
||||
result.push(key);
|
||||
});
|
||||
return result;
|
||||
});
|
||||
|
||||
export default stringToPath;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
export function toggleScreen(domID: string) {
|
||||
const elem = document.getElementById(domID) as HTMLElement;
|
||||
if (!document.fullscreenElement && elem) {
|
||||
elem.requestFullscreen().catch((err) => {
|
||||
console.error(`Error attempting to enable fullscreen mode: ${err.message} (${err.name})`);
|
||||
});
|
||||
} else {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
import stringToPath from "./stringToPath";
|
||||
|
||||
export function modify(config, path, value) {
|
||||
if (typeof config !== 'object' || !path) {
|
||||
return;
|
||||
}
|
||||
|
||||
const paths = stringToPath(path);
|
||||
let oldVal = config;
|
||||
|
||||
for (let index = 0; index < paths.length; index++) {
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (oldVal == null) {
|
||||
return;
|
||||
}
|
||||
const key = paths[index];
|
||||
if (index !== paths.length - 1) {
|
||||
oldVal = oldVal?.[key];
|
||||
|
||||
} else {
|
||||
Object.assign(oldVal, { [key]: value });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function add(config, path, value) {
|
||||
if (typeof config !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
const paths = stringToPath(path);
|
||||
let oldVal = config;
|
||||
|
||||
for (let index = 0; index < paths.length; index++) {
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (oldVal == null) {
|
||||
return;
|
||||
}
|
||||
const key = paths[index];
|
||||
if (index !== paths.length - 1) {
|
||||
oldVal = oldVal?.[key];
|
||||
|
||||
} else {
|
||||
if (Array.isArray(oldVal)) {
|
||||
oldVal.splice(key, 0, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function remove(config, path) {
|
||||
if (typeof config !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
const paths = stringToPath(path);
|
||||
let oldVal = config;
|
||||
|
||||
for (let index = 0; index < paths.length; index++) {
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (oldVal == null) {
|
||||
return;
|
||||
}
|
||||
const key = paths[index];
|
||||
if (index !== paths.length - 1) {
|
||||
oldVal = oldVal?.[key];
|
||||
|
||||
} else {
|
||||
if (Array.isArray(oldVal)) {
|
||||
oldVal.splice(key, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user