@codady/utils 0.0.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/CHANGELOG.md +20 -0
- package/LICENSE +24 -0
- package/README.md +24 -0
- package/dist/utils.cjs.js +113 -0
- package/dist/utils.cjs.min.js +15 -0
- package/dist/utils.esm.js +111 -0
- package/dist/utils.esm.min.js +15 -0
- package/dist/utils.umd.js +119 -0
- package/dist/utils.umd.min.js +15 -0
- package/dist.zip +0 -0
- package/package.json +73 -0
- package/rollup.config.js +68 -0
- package/script-mini.js +41 -0
- package/script-note.js +34 -0
- package/src/deepClone.js +53 -0
- package/src/deepClone.ts +59 -0
- package/src/escapeHTML - /345/211/257/346/234/254.js" +29 -0
- package/src/escapeHTML.js +29 -0
- package/src/escapeHTML.ts +30 -0
- package/src/execluteStr.js +29 -0
- package/src/executeStr.js +36 -0
- package/src/executeStr.ts +42 -0
- package/src/getDataType.js +38 -0
- package/src/getDataType.ts +37 -0
- package/src/parseStr.js +46 -0
- package/src/parseStr.ts +47 -0
- package/src/renderTpl.js +70 -0
- package/src/renderTpl.ts +86 -0
- package/src/requireTypes.js +48 -0
- package/src/requireTypes.ts +54 -0
- package/tsconfig.json +108 -0
package/script-note.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Last modified: 2025/11/15 11:09:56
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync } from 'fs';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { dirname, resolve } from 'path';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
|
|
12
|
+
const pkg = JSON.parse(readFileSync(resolve(__dirname, './package.json'), 'utf8'));
|
|
13
|
+
|
|
14
|
+
const now = new Date();
|
|
15
|
+
const times = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate() + ' ' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();
|
|
16
|
+
|
|
17
|
+
const note = `
|
|
18
|
+
/*!
|
|
19
|
+
* @since Last modified: ${times}
|
|
20
|
+
* @name Utils for web front-end.
|
|
21
|
+
* @version ${pkg.version}
|
|
22
|
+
* @author AXUI development team <3217728223@qq.com>
|
|
23
|
+
* @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
|
|
24
|
+
* @see {@link https://www.axui.cn|Official website}
|
|
25
|
+
* @see {@link https://github.com/codady/utils/issues|github issues}
|
|
26
|
+
* @see {@link https://gitee.com/codady/utils/issues|Gitee issues}
|
|
27
|
+
* @see {@link https://www.npmjs.com/package/@codady/utils|NPM}
|
|
28
|
+
* @issue QQ Group No.1:952502085
|
|
29
|
+
* @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'ax,' 'axui,' 'AX,' and 'AXUI' within the software.
|
|
30
|
+
* @license MIT license
|
|
31
|
+
*/
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
export default note;
|
package/src/deepClone.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/16 09:02:07
|
|
3
|
+
* Deep clone an array or object.
|
|
4
|
+
* Supports Symbol keys. These types are returned directly:
|
|
5
|
+
* Number, String, Boolean, Symbol, HTML*Element, Function, Date, RegExp.
|
|
6
|
+
*
|
|
7
|
+
* @template T
|
|
8
|
+
* @param {T} data - Array or object to clone
|
|
9
|
+
* @returns {T} - New object with different memory address
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const obj = { a: '', b: 0, c: [] };
|
|
13
|
+
* const cloned = deepClone(obj);
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const arr = [{}, {}, {}];
|
|
17
|
+
* const cloned = deepClone(arr);
|
|
18
|
+
*/
|
|
19
|
+
'use strict';
|
|
20
|
+
import getDataType from './getDataType';
|
|
21
|
+
const deepClone = (data) => {
|
|
22
|
+
const dataType = getDataType(data);
|
|
23
|
+
if (dataType === 'Object') {
|
|
24
|
+
const newObj = {};
|
|
25
|
+
const symbols = Object.getOwnPropertySymbols(data);
|
|
26
|
+
// Clone regular properties
|
|
27
|
+
for (const key in data) {
|
|
28
|
+
newObj[key] = deepClone(data[key]);
|
|
29
|
+
}
|
|
30
|
+
// Clone Symbol properties
|
|
31
|
+
if (symbols.length > 0) {
|
|
32
|
+
for (const symbol of symbols) {
|
|
33
|
+
newObj[symbol] = deepClone(data[symbol]);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return newObj;
|
|
37
|
+
}
|
|
38
|
+
else if (dataType === 'Array') {
|
|
39
|
+
return data.map(item => deepClone(item));
|
|
40
|
+
}
|
|
41
|
+
else if (dataType === 'Date') {
|
|
42
|
+
return new Date(data.getTime());
|
|
43
|
+
}
|
|
44
|
+
else if (dataType === 'RegExp') {
|
|
45
|
+
const regex = data;
|
|
46
|
+
return new RegExp(regex.source, regex.flags);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Number, String, Boolean, Symbol,Text,Comment,Set,Map, HTML*Element, Function,Error,Promise,ArrayBuffer,Blob,File, return directly
|
|
50
|
+
return data;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
export default deepClone;
|
package/src/deepClone.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/16 09:02:07
|
|
3
|
+
* Deep clone an array or object.
|
|
4
|
+
* Supports Symbol keys. These types are returned directly:
|
|
5
|
+
* Number, String, Boolean, Symbol, HTML*Element, Function, Date, RegExp.
|
|
6
|
+
*
|
|
7
|
+
* @template T
|
|
8
|
+
* @param {T} data - Array or object to clone
|
|
9
|
+
* @returns {T} - New object with different memory address
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const obj = { a: '', b: 0, c: [] };
|
|
13
|
+
* const cloned = deepClone(obj);
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const arr = [{}, {}, {}];
|
|
17
|
+
* const cloned = deepClone(arr);
|
|
18
|
+
*/
|
|
19
|
+
'use strict';
|
|
20
|
+
import getDataType from './getDataType';
|
|
21
|
+
|
|
22
|
+
const deepClone = <T>(data: T): T => {
|
|
23
|
+
const dataType = getDataType(data);
|
|
24
|
+
|
|
25
|
+
if (dataType === 'Object') {
|
|
26
|
+
const newObj: Record<string | symbol, any> = {};
|
|
27
|
+
const symbols = Object.getOwnPropertySymbols(data);
|
|
28
|
+
|
|
29
|
+
// Clone regular properties
|
|
30
|
+
for (const key in data) {
|
|
31
|
+
newObj[key] = deepClone((data as any)[key]);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Clone Symbol properties
|
|
35
|
+
if (symbols.length > 0) {
|
|
36
|
+
for (const symbol of symbols) {
|
|
37
|
+
newObj[symbol] = deepClone((data as any)[symbol]);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return newObj as T;
|
|
42
|
+
|
|
43
|
+
} else if (dataType === 'Array') {
|
|
44
|
+
return (data as any[]).map(item => deepClone(item)) as T;
|
|
45
|
+
|
|
46
|
+
} else if (dataType === 'Date') {
|
|
47
|
+
return new Date((data as Date).getTime()) as T;
|
|
48
|
+
|
|
49
|
+
} else if (dataType === 'RegExp') {
|
|
50
|
+
const regex = data as RegExp;
|
|
51
|
+
return new RegExp(regex.source, regex.flags) as T;
|
|
52
|
+
|
|
53
|
+
} else {
|
|
54
|
+
// Number, String, Boolean, Symbol,Text,Comment,Set,Map, HTML*Element, Function,Error,Promise,ArrayBuffer,Blob,File, return directly
|
|
55
|
+
return data;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default deepClone;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function escapeHTML
|
|
3
|
+
* @description Escapes HTML characters in a string to prevent XSS attacks.
|
|
4
|
+
* This function replaces special characters such as <, >, &, ", ', etc. with their corresponding HTML entities.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} str - The input string to be escaped.
|
|
7
|
+
* @returns {string} - The escaped string with special HTML characters replaced by HTML entities.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* escapeHTML("<div>Hello & 'world'</div>");
|
|
11
|
+
* // returns "<div>Hello & 'world'</div>"
|
|
12
|
+
*/
|
|
13
|
+
export const escapeHTML = (str) => {
|
|
14
|
+
// Mapping of HTML special characters to their corresponding HTML entities
|
|
15
|
+
const escapes = {
|
|
16
|
+
'&': '&',
|
|
17
|
+
'<': '<',
|
|
18
|
+
'>': '>',
|
|
19
|
+
'"': '"',
|
|
20
|
+
"'": ''',
|
|
21
|
+
'`': '`',
|
|
22
|
+
'=': '=',
|
|
23
|
+
'/': '/'
|
|
24
|
+
};
|
|
25
|
+
// Replace each special character in the input string with its corresponding HTML entity
|
|
26
|
+
return str.replace(/[&<>"'`=\/]/g, (match) => {
|
|
27
|
+
return escapes[match];
|
|
28
|
+
});
|
|
29
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function escapeHTML
|
|
3
|
+
* @description Escapes HTML characters in a string to prevent XSS attacks.
|
|
4
|
+
* This function replaces special characters such as <, >, &, ", ', etc. with their corresponding HTML entities.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} str - The input string to be escaped.
|
|
7
|
+
* @returns {string} - The escaped string with special HTML characters replaced by HTML entities.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* escapeHTML("<div>Hello & 'world'</div>");
|
|
11
|
+
* // returns "<div>Hello & 'world'</div>"
|
|
12
|
+
*/
|
|
13
|
+
export const escapeHTML = (str) => {
|
|
14
|
+
// Mapping of HTML special characters to their corresponding HTML entities
|
|
15
|
+
const escapes = {
|
|
16
|
+
'&': '&',
|
|
17
|
+
'<': '<',
|
|
18
|
+
'>': '>',
|
|
19
|
+
'"': '"',
|
|
20
|
+
"'": ''',
|
|
21
|
+
'`': '`',
|
|
22
|
+
'=': '=',
|
|
23
|
+
'/': '/'
|
|
24
|
+
};
|
|
25
|
+
// Replace each special character in the input string with its corresponding HTML entity
|
|
26
|
+
return str.replace(/[&<>"'`=\/]/g, (match) => {
|
|
27
|
+
return escapes[match];
|
|
28
|
+
});
|
|
29
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function escapeHTML
|
|
3
|
+
* @description Escapes HTML characters in a string to prevent XSS attacks.
|
|
4
|
+
* This function replaces special characters such as <, >, &, ", ', etc. with their corresponding HTML entities.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} str - The input string to be escaped.
|
|
7
|
+
* @returns {string} - The escaped string with special HTML characters replaced by HTML entities.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* escapeHTML("<div>Hello & 'world'</div>");
|
|
11
|
+
* // returns "<div>Hello & 'world'</div>"
|
|
12
|
+
*/
|
|
13
|
+
export const escapeHTML = (str: string): string => {
|
|
14
|
+
// Mapping of HTML special characters to their corresponding HTML entities
|
|
15
|
+
const escapes: { [key: string]: string } = {
|
|
16
|
+
'&': '&',
|
|
17
|
+
'<': '<',
|
|
18
|
+
'>': '>',
|
|
19
|
+
'"': '"',
|
|
20
|
+
"'": ''',
|
|
21
|
+
'`': '`',
|
|
22
|
+
'=': '=',
|
|
23
|
+
'/': '/'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Replace each special character in the input string with its corresponding HTML entity
|
|
27
|
+
return str.replace(/[&<>"'`=\/]/g, (match) => {
|
|
28
|
+
return escapes[match];
|
|
29
|
+
});
|
|
30
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function escapeHTML
|
|
3
|
+
* @description Escapes HTML characters in a string to prevent XSS attacks.
|
|
4
|
+
* This function replaces special characters such as <, >, &, ", ', etc. with their corresponding HTML entities.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} str - The input string to be escaped.
|
|
7
|
+
* @returns {string} - The escaped string with special HTML characters replaced by HTML entities.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* escapeHTML("<div>Hello & 'world'</div>");
|
|
11
|
+
* // returns "<div>Hello & 'world'</div>"
|
|
12
|
+
*/
|
|
13
|
+
export const escapeHTML = (str) => {
|
|
14
|
+
// Mapping of HTML special characters to their corresponding HTML entities
|
|
15
|
+
const escapes = {
|
|
16
|
+
'&': '&',
|
|
17
|
+
'<': '<',
|
|
18
|
+
'>': '>',
|
|
19
|
+
'"': '"',
|
|
20
|
+
"'": ''',
|
|
21
|
+
'`': '`',
|
|
22
|
+
'=': '=',
|
|
23
|
+
'/': '/'
|
|
24
|
+
};
|
|
25
|
+
// Replace each special character in the input string with its corresponding HTML entity
|
|
26
|
+
return str.replace(/[&<>"'`=\/]/g, (match) => {
|
|
27
|
+
return escapes[match];
|
|
28
|
+
});
|
|
29
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import requireTypes from "./requireTypes";
|
|
2
|
+
/**
|
|
3
|
+
* @since Last modified: 2025/11/15 17:36:19
|
|
4
|
+
* @function executeStr
|
|
5
|
+
* @description Executes dynamic JavaScript code with data binding. Supports strict mode and data objects.
|
|
6
|
+
* The function allows the dynamic execution of code with optional binding of the provided data to the function context.
|
|
7
|
+
* If `splitData` is true, the data is split into keys and values for parameterized function execution.
|
|
8
|
+
* This function dynamically generates and executes a new function based on the provided content.
|
|
9
|
+
*
|
|
10
|
+
* @param {string} content - The JavaScript code as a string to execute. This code can contain variables that will be replaced with data values.
|
|
11
|
+
* @param {object|array} data - The data object or array to bind to the code. This is used to replace placeholders or reference `this` inside the code.
|
|
12
|
+
* @param {boolean} [splitData=false] - Whether to split the data into keys and values. If true, the `data` object is converted into individual parameters.
|
|
13
|
+
* @returns {any} - The result of the executed code. This could be any type depending on the content of the code being executed.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
const executeStr = (content, data, splitData = false) => {
|
|
17
|
+
//content要求是字符串格式
|
|
18
|
+
requireTypes(content, 'string', (error) => {
|
|
19
|
+
console.error(error);
|
|
20
|
+
return;
|
|
21
|
+
});
|
|
22
|
+
let dataType = requireTypes(data, ['array', 'object'], (error) => {
|
|
23
|
+
console.error(error);
|
|
24
|
+
return;
|
|
25
|
+
}), result;
|
|
26
|
+
if (splitData && dataType === 'Object') {
|
|
27
|
+
let keys = Object.keys(data), values = Object.values(data), tmp = new Function(...keys, content).bind(data);
|
|
28
|
+
result = tmp(...values);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const tmp = new Function(content).apply(data);
|
|
32
|
+
result = tmp();
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
export default executeStr;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import requireTypes from "./requireTypes";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @since Last modified: 2025/11/15 17:36:19
|
|
5
|
+
* @function executeStr
|
|
6
|
+
* @description Executes dynamic JavaScript code with data binding. Supports strict mode and data objects.
|
|
7
|
+
* The function allows the dynamic execution of code with optional binding of the provided data to the function context.
|
|
8
|
+
* If `splitData` is true, the data is split into keys and values for parameterized function execution.
|
|
9
|
+
* This function dynamically generates and executes a new function based on the provided content.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} content - The JavaScript code as a string to execute. This code can contain variables that will be replaced with data values.
|
|
12
|
+
* @param {object|array} data - The data object or array to bind to the code. This is used to replace placeholders or reference `this` inside the code.
|
|
13
|
+
* @param {boolean} [splitData=false] - Whether to split the data into keys and values. If true, the `data` object is converted into individual parameters.
|
|
14
|
+
* @returns {any} - The result of the executed code. This could be any type depending on the content of the code being executed.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
const executeStr = (content: string, data: any, splitData: boolean = false): any => {
|
|
18
|
+
//content要求是字符串格式
|
|
19
|
+
requireTypes(content, 'string', (error) => {
|
|
20
|
+
console.error(error);
|
|
21
|
+
return;
|
|
22
|
+
});
|
|
23
|
+
let dataType = requireTypes(data, ['array', 'object'], (error) => {
|
|
24
|
+
console.error(error);
|
|
25
|
+
return;
|
|
26
|
+
}),
|
|
27
|
+
result;
|
|
28
|
+
|
|
29
|
+
if (splitData && dataType === 'Object') {
|
|
30
|
+
let keys = Object.keys(data),
|
|
31
|
+
values = Object.values(data),
|
|
32
|
+
tmp = new Function(...keys, content).bind(data);
|
|
33
|
+
result = tmp(...values);
|
|
34
|
+
} else {
|
|
35
|
+
const tmp = new Function(content).apply(data);
|
|
36
|
+
result = tmp();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default executeStr;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/16 09:00:41
|
|
3
|
+
* @function getDataType
|
|
4
|
+
* @description Get object type.Can detect object types such as Array, Object, Function,
|
|
5
|
+
* Window,Location,History,Navigator,XMLHttpRequest, WebSocket,FileReader,MediaStream
|
|
6
|
+
* Class , String, Number, Boolean, Date, Symbol ,File ,Blob,
|
|
7
|
+
* Error,Promise,ArrayBuffer,TypedArray, Set, weakSet, Map, weakMap, Null, Undefined,
|
|
8
|
+
* Text, DocumentFragment,Comment, XMLDocument, ProcessingInstruction, Range, TreeWalker,
|
|
9
|
+
* NodeIterator,SVGSVGElement,MathMLElement, HTMLxxxElement (Dom nodes all contain HTML),Promise,AsyncFunction and Instance.
|
|
10
|
+
* @param {*} obj - Can be any object
|
|
11
|
+
* @returns {string} - Returns the name of the data type.
|
|
12
|
+
*/
|
|
13
|
+
'use strict';
|
|
14
|
+
const getDataType = (obj) => {
|
|
15
|
+
let tmp = Object.prototype.toString.call(obj).slice(8, -1), result;
|
|
16
|
+
if (tmp === 'Function' && /^\s*class\s+/.test(obj.toString())) {
|
|
17
|
+
result = 'Class';
|
|
18
|
+
}
|
|
19
|
+
else if (tmp === 'Object' && Object.getPrototypeOf(obj) !== Object.prototype) {
|
|
20
|
+
result = 'Instance';
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
result = tmp;
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
//document.createElement -> HTMLxxxElement
|
|
27
|
+
//document.createDocumentFragment() -> DocumentFragment
|
|
28
|
+
//document.createComment() -> Comment
|
|
29
|
+
//document.createTextNode -> Text
|
|
30
|
+
//document.createCDATASection() -> XMLDocument
|
|
31
|
+
//document.createProcessingInstruction() -> ProcessingInstruction
|
|
32
|
+
//document.createRange() -> Range
|
|
33
|
+
//document.createTreeWalker() -> TreeWalker
|
|
34
|
+
//document.createNodeIterator() -> NodeIterator
|
|
35
|
+
//document.createElementNS('http://www.w3.org/2000/svg', 'svg'); -> SVGSVGElement
|
|
36
|
+
//document.createElementNS('http://www.w3.org/1998/Math/MathML', 'math'); -> MathMLElement
|
|
37
|
+
};
|
|
38
|
+
export default getDataType;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/16 09:00:41
|
|
3
|
+
* @function getDataType
|
|
4
|
+
* @description Get object type.Can detect object types such as Array, Object, Function,
|
|
5
|
+
* Window,Location,History,Navigator,XMLHttpRequest, WebSocket,FileReader,MediaStream
|
|
6
|
+
* Class , String, Number, Boolean, Date, Symbol ,File ,Blob,
|
|
7
|
+
* Error,Promise,ArrayBuffer,TypedArray, Set, weakSet, Map, weakMap, Null, Undefined,
|
|
8
|
+
* Text, DocumentFragment,Comment, XMLDocument, ProcessingInstruction, Range, TreeWalker,
|
|
9
|
+
* NodeIterator,SVGSVGElement,MathMLElement, HTMLxxxElement (Dom nodes all contain HTML),Promise,AsyncFunction and Instance.
|
|
10
|
+
* @param {*} obj - Can be any object
|
|
11
|
+
* @returns {string} - Returns the name of the data type.
|
|
12
|
+
*/
|
|
13
|
+
'use strict';
|
|
14
|
+
const getDataType = (obj: any): string => {
|
|
15
|
+
let tmp = Object.prototype.toString.call(obj).slice(8, -1),
|
|
16
|
+
result;
|
|
17
|
+
if (tmp === 'Function' && /^\s*class\s+/.test(obj.toString())) {
|
|
18
|
+
result = 'Class';
|
|
19
|
+
} else if (tmp === 'Object' && Object.getPrototypeOf(obj) !== Object.prototype) {
|
|
20
|
+
result = 'Instance';
|
|
21
|
+
} else {
|
|
22
|
+
result = tmp;
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
//document.createElement -> HTMLxxxElement
|
|
26
|
+
//document.createDocumentFragment() -> DocumentFragment
|
|
27
|
+
//document.createComment() -> Comment
|
|
28
|
+
//document.createTextNode -> Text
|
|
29
|
+
//document.createCDATASection() -> XMLDocument
|
|
30
|
+
//document.createProcessingInstruction() -> ProcessingInstruction
|
|
31
|
+
//document.createRange() -> Range
|
|
32
|
+
//document.createTreeWalker() -> TreeWalker
|
|
33
|
+
//document.createNodeIterator() -> NodeIterator
|
|
34
|
+
//document.createElementNS('http://www.w3.org/2000/svg', 'svg'); -> SVGSVGElement
|
|
35
|
+
//document.createElementNS('http://www.w3.org/1998/Math/MathML', 'math'); -> MathMLElement
|
|
36
|
+
};
|
|
37
|
+
export default getDataType;
|
package/src/parseStr.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/11/15 16:52:18
|
|
3
|
+
* @function parseStr
|
|
4
|
+
* @description Safely parses a string content and evaluates it based on the provided method.
|
|
5
|
+
* This function allows parsing content as JSON, or using custom evaluation via the provided method,
|
|
6
|
+
* with the ability to bind a custom context (`this`) during evaluation.
|
|
7
|
+
*
|
|
8
|
+
* @param {object} options - The options for parsing the string.
|
|
9
|
+
* @param {string | null} options.content - The string content to be parsed. (required)
|
|
10
|
+
* @param {('new Function' | 'JSON.parse' | T_fn)} [options.method='new Function'] - The method to use for parsing.
|
|
11
|
+
* @param {boolean} [options.catchable=false] - Whether to throw an error on failure or return an empty value.
|
|
12
|
+
* @param {boolean} [options.safe=false] - Whether to escape HTML characters to prevent XSS attacks.
|
|
13
|
+
* @param {any} [options.bind] - The context (`this`) to bind during evaluation.
|
|
14
|
+
* @param {T_fn} [options.error] - The callback function to call when an error occurs.
|
|
15
|
+
* @returns {any} The parsed result.
|
|
16
|
+
*/
|
|
17
|
+
'use strict';
|
|
18
|
+
import { escapeHTML } from "./escapeHTML";
|
|
19
|
+
import requireTypes from "./requireTypes";
|
|
20
|
+
const parseStr = ({ content = '', method = 'new Function', catchable = false, safe = false, bind, error }) => {
|
|
21
|
+
//必须是字符串格式
|
|
22
|
+
requireTypes(content, 'String', (error) => {
|
|
23
|
+
console.error(error);
|
|
24
|
+
return null;
|
|
25
|
+
});
|
|
26
|
+
let result, trim = content?.trim();
|
|
27
|
+
if (!trim)
|
|
28
|
+
return '';
|
|
29
|
+
//防止注入攻击,则过滤文本
|
|
30
|
+
safe && (trim = escapeHTML(trim));
|
|
31
|
+
try {
|
|
32
|
+
//method可能是一个函数
|
|
33
|
+
result = typeof method === 'function' ? method(trim) :
|
|
34
|
+
method === 'JSON.parse' ? JSON.parse(trim) :
|
|
35
|
+
//允许绑定this,也就是说content中可以使用this关键字
|
|
36
|
+
(bind ? new Function(`"use strict"; return ${trim}`).apply(bind) : new Function(`"use strict"; return ${trim}`)());
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
error && error(err);
|
|
40
|
+
//如果抛出错误则会阻止执行,不会返回result
|
|
41
|
+
if (catchable)
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
export default parseStr;
|
package/src/parseStr.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/11/15 16:52:18
|
|
3
|
+
* @function parseStr
|
|
4
|
+
* @description Safely parses a string content and evaluates it based on the provided method.
|
|
5
|
+
* This function allows parsing content as JSON, or using custom evaluation via the provided method,
|
|
6
|
+
* with the ability to bind a custom context (`this`) during evaluation.
|
|
7
|
+
*
|
|
8
|
+
* @param {object} options - The options for parsing the string.
|
|
9
|
+
* @param {string | null} options.content - The string content to be parsed. (required)
|
|
10
|
+
* @param {('new Function' | 'JSON.parse' | T_fn)} [options.method='new Function'] - The method to use for parsing.
|
|
11
|
+
* @param {boolean} [options.catchable=false] - Whether to throw an error on failure or return an empty value.
|
|
12
|
+
* @param {boolean} [options.safe=false] - Whether to escape HTML characters to prevent XSS attacks.
|
|
13
|
+
* @param {any} [options.bind] - The context (`this`) to bind during evaluation.
|
|
14
|
+
* @param {T_fn} [options.error] - The callback function to call when an error occurs.
|
|
15
|
+
* @returns {any} The parsed result.
|
|
16
|
+
*/
|
|
17
|
+
'use strict';
|
|
18
|
+
import { T_fn, T_null, T_obj } from "../types/utils";
|
|
19
|
+
import { escapeHTML } from "./escapeHTML";
|
|
20
|
+
import requireTypes from "./requireTypes";
|
|
21
|
+
const parseStr = ({ content = '', method = 'new Function', catchable = false, safe = false, bind, error }: { content: string | T_null, method?: 'new Function' | 'JSON.parse' | T_fn, catchable?: boolean, safe?: boolean, bind?: any, error?: T_fn }) => {
|
|
22
|
+
|
|
23
|
+
//必须是字符串格式
|
|
24
|
+
requireTypes(content, 'String', (error) => {
|
|
25
|
+
console.error(error);
|
|
26
|
+
return null;
|
|
27
|
+
});
|
|
28
|
+
let result,
|
|
29
|
+
trim = content?.trim();
|
|
30
|
+
if (!trim) return '';
|
|
31
|
+
//防止注入攻击,则过滤文本
|
|
32
|
+
safe && (trim = escapeHTML(trim));
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
//method可能是一个函数
|
|
36
|
+
result = typeof method === 'function' ? method(trim) :
|
|
37
|
+
method === 'JSON.parse' ? JSON.parse(trim) :
|
|
38
|
+
//允许绑定this,也就是说content中可以使用this关键字
|
|
39
|
+
(bind ? new Function(`"use strict"; return ${trim}`).apply(bind) : new Function(`"use strict"; return ${trim}`)());
|
|
40
|
+
} catch (err) {
|
|
41
|
+
error && error(err);
|
|
42
|
+
//如果抛出错误则会阻止执行,不会返回result
|
|
43
|
+
if (catchable) throw err;
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
export default parseStr;
|
package/src/renderTpl.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/11/15 16:24:20
|
|
3
|
+
* @function renderTpl
|
|
4
|
+
* @description Get template string through parameters.Cut the template strings into fragments through labels, and put into the array through the PUSH method, and finally merge into a new string.
|
|
5
|
+
* @param {string} html - Text string with variables, for example: html=`I like {{this.name}}, she is {{this.age}} years old`.
|
|
6
|
+
* @param {object|array} data - Variable key-value pairs, for example: data={name:'Lily',age:20} or [{name:'Lily'},{name:'Mark'}].
|
|
7
|
+
* @param {Object} [options] - Configuration options to control the rendering behavior:
|
|
8
|
+
* @param {boolean} [options.safe=false] - If true, HTML special characters in the template will be escaped to prevent XSS attacks. Default is `false`.
|
|
9
|
+
* @param {boolean} [options.strict=false] - If true, the template engine will require using `this` to access properties, especially for arrays. Default is `false`.
|
|
10
|
+
* @param {string} [options.start='{{'] - The opening delimiter for template variables. Default is `{{`.
|
|
11
|
+
* @param {string} [options.end='}}'] - The closing delimiter for template variables. Default is `}}`.
|
|
12
|
+
* @param {string} [options.suffix='/'] - The suffix for ending script-like expressions. Default is `/`. This is used to close template expressions like `{{this.fn() /}}`.
|
|
13
|
+
* @returns {string} - The string after the variables are replaced with data.
|
|
14
|
+
*/
|
|
15
|
+
'use strict';
|
|
16
|
+
import { escapeHTML } from "./escapeHTML";
|
|
17
|
+
import requireTypes from "./requireTypes";
|
|
18
|
+
const renderTpl = (html, data, options = {}) => {
|
|
19
|
+
requireTypes(html, 'string', (error) => {
|
|
20
|
+
//不符合要求的类型
|
|
21
|
+
console.error(error);
|
|
22
|
+
return '';
|
|
23
|
+
});
|
|
24
|
+
if (!html.trim())
|
|
25
|
+
return '';
|
|
26
|
+
let dataType = requireTypes(data, ['array', 'object'], (error) => {
|
|
27
|
+
//不符合要求的类型
|
|
28
|
+
console.error(error);
|
|
29
|
+
return html;
|
|
30
|
+
});
|
|
31
|
+
//data={}/[]
|
|
32
|
+
if (Object.keys(data).length === 0) {
|
|
33
|
+
console.warn('Data is empty ({}/[]), no rendering performed, original text outputted.');
|
|
34
|
+
return html;
|
|
35
|
+
}
|
|
36
|
+
let opts = Object.assign({ safe: false, strict: false, start: '{{', end: '}}', suffix: '/' }, options), tplStr = opts.safe ? escapeHTML(html) : html,
|
|
37
|
+
//regStart='\\{\\{'
|
|
38
|
+
regStart = opts.start.split('').map(k => '\\' + k).join(''),
|
|
39
|
+
//regEnd='\\}\\}'
|
|
40
|
+
regEnd = opts.end.split('').map(k => '\\' + k).join(''), tplReg = new RegExp(`${regStart}([\\s\\S]+?)?${regEnd}`, 'g'), code = '"use strict";let str=[];\n', cursor = 0, match, result = '', add = (fragment, isScript) => {
|
|
41
|
+
isScript ? (code += (fragment.endsWith(opts.suffix) ? fragment.replace('=>', '=>').slice(0, -1) + '\n' : 'str.push(' + fragment + ');\n'))
|
|
42
|
+
: (code += (fragment !== '' ? 'str.push("' + fragment.replace(/"/g, '\\"') + '");\n' : ''));
|
|
43
|
+
return add;
|
|
44
|
+
};
|
|
45
|
+
while (match = tplReg.exec(tplStr)) {
|
|
46
|
+
add(tplStr.slice(cursor, match.index))(match[1], true);
|
|
47
|
+
cursor = match.index + match[0].length;
|
|
48
|
+
}
|
|
49
|
+
add(tplStr.slice(cursor));
|
|
50
|
+
code += `return str.join('');`;
|
|
51
|
+
try {
|
|
52
|
+
if (opts.strict || dataType === 'Array') {
|
|
53
|
+
//严格模式,或者是数组数据,则必须使用this
|
|
54
|
+
result = new Function(code.replace(/[\r\t\n]/g, '')).apply(data);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
////非严格模式,且是对象,则可省略this
|
|
58
|
+
let keys = Object.keys(data), values = Object.values(data),
|
|
59
|
+
//keys传参,this依然可指向data
|
|
60
|
+
tmp = new Function(...keys, code.replace(/[\r\t\n]/g, '')).bind(data);
|
|
61
|
+
//执行时以value赋值
|
|
62
|
+
result = tmp(...values);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
console.error(`'${err.message}'`, ' in \n', code, '\n');
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
};
|
|
70
|
+
export default renderTpl;
|