@codady/utils 0.0.22 → 0.0.23

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 CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  All changes to Utils including new features, updates, and removals are documented here.
4
4
 
5
- ## [v0.0.22] - 2026-1-6
5
+ ## [v0.0.23] - 2026-1-7
6
6
 
7
7
  ### Distribution Files
8
- * **JS**: https://unpkg.com/@codady/utils@0.0.22/dist/js/utils.js
9
- * **Zip**:https://unpkg.com/@codady/utils@0.0.22/dist.zip
8
+ * **JS**: https://unpkg.com/@codady/utils@0.0.23/dist/js/utils.js
9
+ * **Zip**:https://unpkg.com/@codady/utils@0.0.23/dist.zip
10
10
 
11
11
  ### Changes
12
12
 
@@ -14,7 +14,7 @@ All changes to Utils including new features, updates, and removals are documente
14
14
  * Null
15
15
 
16
16
  #### Added
17
- * Added the functions `svgToBase64`.新增`svgToBase64`函数。
17
+ * Added the functions `getSvgUri`,`fileToBase64`.新增`getSvgUri`、`fileToBase64`函数。
18
18
 
19
19
 
20
20
  #### Removed
package/dist/utils.cjs.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2026-1-6 21:54:24
3
+ * @since Last modified: 2026-1-7 8:57:42
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.22
5
+ * @version 0.0.23
6
6
  * @author AXUI development team <3217728223@qq.com>
7
7
  * @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.
8
8
  * @see {@link https://www.axui.cn|Official website}
@@ -901,12 +901,50 @@ const createEl = (name, attrs, content) => {
901
901
  return rootEl;
902
902
  };
903
903
 
904
- const svgToBase64 = (svgString) => {
905
- // 1. This method provides the best compatibility (escaping special characters)
906
- const encoded = encodeURIComponent(svgString)
907
- .replace(/'/g, "%27")
908
- .replace(/"/g, "%22");
909
- return `data:image/svg+xml;charset=utf-8,${encoded}`;
904
+ const getSvgUri = (svgString) => {
905
+ // 1. Minify the SVG: Remove line breaks and collapse multiple spaces
906
+ // to ensure the resulting URI is a single, clean line.
907
+ const cleanedSvg = svgString
908
+ .replace(/\n/g, '')
909
+ .replace(/\s+/g, ' ')
910
+ .trim();
911
+ // 2. Character Encoding:
912
+ // We escape specific characters that have special meanings in URLs or
913
+ // can break CSS parser logic (especially when used in background-image: url()).
914
+ // - '#' (Hash) is escaped to '%23' because it's a URL fragment identifier.
915
+ // - '%' (Percent) is escaped to '%25' as it is the escape character itself.
916
+ // - '<' and '>' are escaped to '%3C' and '%3E' for URL safety.
917
+ // - '{' and '}' are escaped to '%7B' and '%7D' to avoid conflicts with CSS block syntax.
918
+ const encoded = cleanedSvg
919
+ .replace(/%/g, '%25')
920
+ .replace(/#/g, '%23')
921
+ .replace(/{/g, '%7B')
922
+ .replace(/}/g, '%7D')
923
+ .replace(/</g, '%3C')
924
+ .replace(/>/g, '%3E');
925
+ return `data:image/svg+xml;utf8,${encoded}`;
926
+ };
927
+
928
+ const fileToBase64 = (file) => {
929
+ return new Promise((resolve, reject) => {
930
+ const reader = new FileReader();
931
+ // Triggered when the read operation is successfully completed
932
+ reader.onload = () => {
933
+ // When using readAsDataURL, the result is guaranteed to be a string
934
+ if (typeof reader.result === 'string') {
935
+ resolve(reader.result);
936
+ }
937
+ else {
938
+ reject(new Error('FileReader result is not a string'));
939
+ }
940
+ };
941
+ // Triggered when the read operation encounters an error
942
+ reader.onerror = () => {
943
+ reject(reader.error || new Error('Unknown error occurred during file reading'));
944
+ };
945
+ // Initiates the reading process to convert the file into a Data URL
946
+ reader.readAsDataURL(file);
947
+ });
910
948
  };
911
949
 
912
950
  const utils = {
@@ -930,7 +968,8 @@ const utils = {
930
968
  getEl,
931
969
  getEls,
932
970
  createEl,
933
- svgToBase64,
971
+ getSvgUri,
972
+ fileToBase64,
934
973
  };
935
974
 
936
975
  module.exports = utils;
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2026-1-6 21:54:24
2
+ * @since Last modified: 2026-1-7 8:57:42
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.22
4
+ * @version 0.0.23
5
5
  * @author AXUI development team <3217728223@qq.com>
6
6
  * @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.
7
7
  * @see {@link https://www.axui.cn|Official website}
@@ -12,4 +12,4 @@
12
12
  * @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.
13
13
  * @license MIT license
14
14
  */
15
- "use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let n,o=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const n of r)t[n]=deepClone(e[n],{...a,parent:e});n=t}else if("Array"===r&&a.cloneArray)n=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,n]of e)t.set(deepClone(r,a),deepClone(n,{...a,parent:e}));n=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));n=t}else if("Date"===r&&a.cloneDate)n=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;n=new RegExp(t.source,t.flags)}else n=e,o=!1;return a.onAfterClone?.({output:n,input:e,type:r,cloned:o,parent:a.parent}),n},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:n={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const o={};for(let s of a)o[s]=function(...a){const o={},l=e.length;switch(s){case"push":case"unshift":o.addedItems=[...a];break;case"pop":o.poppedItem=e[l-1];break;case"shift":o.shiftedItem=e[0];break;case"splice":const[t,r]=a,n=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-n:r;o.deletedItems=e.slice(n,n+s);break;case"sort":case"reverse":o.oldSnapshot=[...e];break;case"fill":case"copyWithin":const i=a[1]||0,c=void 0===a[2]?l:a[2];o.oldItems=e.slice(i,c),o.start=i,o.end=c}t?.(o);const i=Array.prototype[s].apply(e,a),c={value:i,key:s,args:a,context:o,target:e,...n};return r?.(c),i};return o},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],n=getDataType(e),o=n.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=o.includes("html")?"element":o;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,n)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return n},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,n=e.base36;return`${t?t+"-":""}${Date.now()}${n?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:n={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)setMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:n={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)mapMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let n,o,s=getDataType(e),l=getDataType(t),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(o=deepMergeObjects(e,t,a),n="Object"):"Array"===s&&"Array"===l?(o=deepMergeArrays(e,t,a),n="Array"):"Set"===s&&"Set"===l?(o=deepMergeSets(e,t,a),n="Set"):"Map"===s&&"Map"===l?(o=deepMergeMaps(e,t,a),n="Map"):(i=!1,o=e),a?.onAfterMerge?.({result:o,target:e,source:t,targetType:s,sourceType:l,mergeType:n,parent:r.parent}),{result:o,flag:i,mergeType:n}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),n=getDataType(t);if("Object"!==a||"Object"!==n)return e;const o=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=o.targetClone?shallowCopy(e):e;for(let e in t){const a=s[e],n=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(a,n,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=n;else{let t=o.useEnable?mergeEnableObject(a,n):n;a!==t&&null===t?"ignore"===o.nullBehavior||("delete"===o.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):a!==t&&void 0===t?"ignore"===o.undefinedBehavior||("delete"===o.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=n):s[e]=n}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&o.inheritMissing&&(s[e]=n)}if(o.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),n=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=n.length));e++){smartMerger(n[e],t[e],{...a,parent:n}).flag||(n[e]=t[e])}else"concat"===a.dataMode||(n.length=0),n.push(...t);return n},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Map([...e]):e;for(const[e,o]of t.entries())if(n.has(e)){const t=n.get(e),r=o,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&n.set(e,s.result):n.set(e,r)}else r.inheritMissing&&n.set(e,o);return n},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...n],r=[...t],o=smartMerger(e,r,a);n.clear();for(let e of o.result)n.add(e)}else if("concat"===a.dataMode)for(let e of t)n.add(e);else{n.clear();for(let e of t)n.add(e)}return n};return smartMerger(e,t,a).result},getEl=(e,t=document.body)=>{let r=getDataType(e),a=getDataType(t),n=a.includes("HTML")||"ShadowRoot"===a?t:document.querySelector(t),o=n&&n instanceof HTMLTemplateElement?n.content:n,s=null;if(e)if(r.includes("HTML"))s=e;else if("String"===r)try{s=(o||document).querySelector(e.trim())}catch{s=null}return s},isEmpty=e=>{let t,r=getDataType(e);return t=!e||("Object"===r?0===Object.keys(e).length:"Array"===r?""===e.join(""):"Function"===r?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===r?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===r||"Map"===r?0===e.size:"Date"===r?isNaN(e.getTime()):"RegExp"===r?""===e.source:"ArrayBuffer"===r?0===e.byteLength:"NodeList"===r||"HTMLCollection"===r||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===r||e instanceof Error?""===e.message:!(!r.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(r))&&0===e.length),t},getEls=(e,t=document.body)=>{let r=getDataType(e),a=getEl(t),n=a&&a instanceof HTMLTemplateElement?a.content:a||document,o=[];return isEmpty(e)?o:(r.includes("HTML")?o.push(e):"String"===r?o=(e=e.trim()).split(",").map(e=>[...n.querySelectorAll(e)]).flat():"Array"===r&&(o=e.map(e=>getEl(e,a))),o.filter(Boolean))},createEl=(e,t,r)=>{let a=(e=e||"div").toUpperCase().trim(),n=document.createElement(a),o=getDataType(t);if(t&&"Object"===o)for(let e in t)t.hasOwnProperty(e)&&n.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let r=getDataType(t);if("TEMPLATE"===a)e.innerHTML=t.toString();else if("Array"===r&&t.length>0)for(let r of t){if(getDataType(r).includes("HTML"))e.appendChild(r);else{let t=createEl(r.name,r.attrs,r.content);t&&e.appendChild(t)}}else if(r.includes("HTML"))e.appendChild(t);else if("String"===r&&t.trim().startsWith("#")&&t.trim().length>1){let r=getEl(t);if(!r)return;"TEMPLATE"===r.nodeName?e.appendChild(r.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",r.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(n,r),n},svgToBase64=e=>`data:image/svg+xml;charset=utf-8,${encodeURIComponent(e).replace(/'/g,"%27").replace(/"/g,"%22")}`,utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:getEls,createEl:createEl,svgToBase64:svgToBase64};module.exports=utils;
15
+ "use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let n,o=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const n of r)t[n]=deepClone(e[n],{...a,parent:e});n=t}else if("Array"===r&&a.cloneArray)n=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,n]of e)t.set(deepClone(r,a),deepClone(n,{...a,parent:e}));n=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));n=t}else if("Date"===r&&a.cloneDate)n=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;n=new RegExp(t.source,t.flags)}else n=e,o=!1;return a.onAfterClone?.({output:n,input:e,type:r,cloned:o,parent:a.parent}),n},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:n={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const o={};for(let s of a)o[s]=function(...a){const o={},l=e.length;switch(s){case"push":case"unshift":o.addedItems=[...a];break;case"pop":o.poppedItem=e[l-1];break;case"shift":o.shiftedItem=e[0];break;case"splice":const[t,r]=a,n=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-n:r;o.deletedItems=e.slice(n,n+s);break;case"sort":case"reverse":o.oldSnapshot=[...e];break;case"fill":case"copyWithin":const i=a[1]||0,c=void 0===a[2]?l:a[2];o.oldItems=e.slice(i,c),o.start=i,o.end=c}t?.(o);const i=Array.prototype[s].apply(e,a),c={value:i,key:s,args:a,context:o,target:e,...n};return r?.(c),i};return o},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],n=getDataType(e),o=n.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=o.includes("html")?"element":o;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,n)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return n},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,n=e.base36;return`${t?t+"-":""}${Date.now()}${n?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:n={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)setMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:n={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)mapMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let n,o,s=getDataType(e),l=getDataType(t),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(o=deepMergeObjects(e,t,a),n="Object"):"Array"===s&&"Array"===l?(o=deepMergeArrays(e,t,a),n="Array"):"Set"===s&&"Set"===l?(o=deepMergeSets(e,t,a),n="Set"):"Map"===s&&"Map"===l?(o=deepMergeMaps(e,t,a),n="Map"):(i=!1,o=e),a?.onAfterMerge?.({result:o,target:e,source:t,targetType:s,sourceType:l,mergeType:n,parent:r.parent}),{result:o,flag:i,mergeType:n}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),n=getDataType(t);if("Object"!==a||"Object"!==n)return e;const o=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=o.targetClone?shallowCopy(e):e;for(let e in t){const a=s[e],n=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(a,n,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=n;else{let t=o.useEnable?mergeEnableObject(a,n):n;a!==t&&null===t?"ignore"===o.nullBehavior||("delete"===o.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):a!==t&&void 0===t?"ignore"===o.undefinedBehavior||("delete"===o.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=n):s[e]=n}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&o.inheritMissing&&(s[e]=n)}if(o.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),n=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=n.length));e++){smartMerger(n[e],t[e],{...a,parent:n}).flag||(n[e]=t[e])}else"concat"===a.dataMode||(n.length=0),n.push(...t);return n},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Map([...e]):e;for(const[e,o]of t.entries())if(n.has(e)){const t=n.get(e),r=o,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&n.set(e,s.result):n.set(e,r)}else r.inheritMissing&&n.set(e,o);return n},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...n],r=[...t],o=smartMerger(e,r,a);n.clear();for(let e of o.result)n.add(e)}else if("concat"===a.dataMode)for(let e of t)n.add(e);else{n.clear();for(let e of t)n.add(e)}return n};return smartMerger(e,t,a).result},getEl=(e,t=document.body)=>{let r=getDataType(e),a=getDataType(t),n=a.includes("HTML")||"ShadowRoot"===a?t:document.querySelector(t),o=n&&n instanceof HTMLTemplateElement?n.content:n,s=null;if(e)if(r.includes("HTML"))s=e;else if("String"===r)try{s=(o||document).querySelector(e.trim())}catch{s=null}return s},isEmpty=e=>{let t,r=getDataType(e);return t=!e||("Object"===r?0===Object.keys(e).length:"Array"===r?""===e.join(""):"Function"===r?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===r?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===r||"Map"===r?0===e.size:"Date"===r?isNaN(e.getTime()):"RegExp"===r?""===e.source:"ArrayBuffer"===r?0===e.byteLength:"NodeList"===r||"HTMLCollection"===r||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===r||e instanceof Error?""===e.message:!(!r.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(r))&&0===e.length),t},getEls=(e,t=document.body)=>{let r=getDataType(e),a=getEl(t),n=a&&a instanceof HTMLTemplateElement?a.content:a||document,o=[];return isEmpty(e)?o:(r.includes("HTML")?o.push(e):"String"===r?o=(e=e.trim()).split(",").map(e=>[...n.querySelectorAll(e)]).flat():"Array"===r&&(o=e.map(e=>getEl(e,a))),o.filter(Boolean))},createEl=(e,t,r)=>{let a=(e=e||"div").toUpperCase().trim(),n=document.createElement(a),o=getDataType(t);if(t&&"Object"===o)for(let e in t)t.hasOwnProperty(e)&&n.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let r=getDataType(t);if("TEMPLATE"===a)e.innerHTML=t.toString();else if("Array"===r&&t.length>0)for(let r of t){if(getDataType(r).includes("HTML"))e.appendChild(r);else{let t=createEl(r.name,r.attrs,r.content);t&&e.appendChild(t)}}else if(r.includes("HTML"))e.appendChild(t);else if("String"===r&&t.trim().startsWith("#")&&t.trim().length>1){let r=getEl(t);if(!r)return;"TEMPLATE"===r.nodeName?e.appendChild(r.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",r.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(n,r),n},getSvgUri=e=>`data:image/svg+xml;utf8,${e.replace(/\n/g,"").replace(/\s+/g," ").trim().replace(/%/g,"%25").replace(/#/g,"%23").replace(/{/g,"%7B").replace(/}/g,"%7D").replace(/</g,"%3C").replace(/>/g,"%3E")}`,fileToBase64=e=>new Promise((t,r)=>{const a=new FileReader;a.onload=()=>{"string"==typeof a.result?t(a.result):r(new Error("FileReader result is not a string"))},a.onerror=()=>{r(a.error||new Error("Unknown error occurred during file reading"))},a.readAsDataURL(e)}),utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:getEls,createEl:createEl,getSvgUri:getSvgUri,fileToBase64:fileToBase64};module.exports=utils;
package/dist/utils.esm.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2026-1-6 21:54:24
3
+ * @since Last modified: 2026-1-7 8:57:42
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.22
5
+ * @version 0.0.23
6
6
  * @author AXUI development team <3217728223@qq.com>
7
7
  * @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.
8
8
  * @see {@link https://www.axui.cn|Official website}
@@ -899,12 +899,50 @@ const createEl = (name, attrs, content) => {
899
899
  return rootEl;
900
900
  };
901
901
 
902
- const svgToBase64 = (svgString) => {
903
- // 1. This method provides the best compatibility (escaping special characters)
904
- const encoded = encodeURIComponent(svgString)
905
- .replace(/'/g, "%27")
906
- .replace(/"/g, "%22");
907
- return `data:image/svg+xml;charset=utf-8,${encoded}`;
902
+ const getSvgUri = (svgString) => {
903
+ // 1. Minify the SVG: Remove line breaks and collapse multiple spaces
904
+ // to ensure the resulting URI is a single, clean line.
905
+ const cleanedSvg = svgString
906
+ .replace(/\n/g, '')
907
+ .replace(/\s+/g, ' ')
908
+ .trim();
909
+ // 2. Character Encoding:
910
+ // We escape specific characters that have special meanings in URLs or
911
+ // can break CSS parser logic (especially when used in background-image: url()).
912
+ // - '#' (Hash) is escaped to '%23' because it's a URL fragment identifier.
913
+ // - '%' (Percent) is escaped to '%25' as it is the escape character itself.
914
+ // - '<' and '>' are escaped to '%3C' and '%3E' for URL safety.
915
+ // - '{' and '}' are escaped to '%7B' and '%7D' to avoid conflicts with CSS block syntax.
916
+ const encoded = cleanedSvg
917
+ .replace(/%/g, '%25')
918
+ .replace(/#/g, '%23')
919
+ .replace(/{/g, '%7B')
920
+ .replace(/}/g, '%7D')
921
+ .replace(/</g, '%3C')
922
+ .replace(/>/g, '%3E');
923
+ return `data:image/svg+xml;utf8,${encoded}`;
924
+ };
925
+
926
+ const fileToBase64 = (file) => {
927
+ return new Promise((resolve, reject) => {
928
+ const reader = new FileReader();
929
+ // Triggered when the read operation is successfully completed
930
+ reader.onload = () => {
931
+ // When using readAsDataURL, the result is guaranteed to be a string
932
+ if (typeof reader.result === 'string') {
933
+ resolve(reader.result);
934
+ }
935
+ else {
936
+ reject(new Error('FileReader result is not a string'));
937
+ }
938
+ };
939
+ // Triggered when the read operation encounters an error
940
+ reader.onerror = () => {
941
+ reject(reader.error || new Error('Unknown error occurred during file reading'));
942
+ };
943
+ // Initiates the reading process to convert the file into a Data URL
944
+ reader.readAsDataURL(file);
945
+ });
908
946
  };
909
947
 
910
948
  const utils = {
@@ -928,7 +966,8 @@ const utils = {
928
966
  getEl,
929
967
  getEls,
930
968
  createEl,
931
- svgToBase64,
969
+ getSvgUri,
970
+ fileToBase64,
932
971
  };
933
972
 
934
973
  export { utils as default };
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2026-1-6 21:54:24
2
+ * @since Last modified: 2026-1-7 8:57:42
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.22
4
+ * @version 0.0.23
5
5
  * @author AXUI development team <3217728223@qq.com>
6
6
  * @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.
7
7
  * @see {@link https://www.axui.cn|Official website}
@@ -12,4 +12,4 @@
12
12
  * @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.
13
13
  * @license MIT license
14
14
  */
15
- const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let n,o=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const n of r)t[n]=deepClone(e[n],{...a,parent:e});n=t}else if("Array"===r&&a.cloneArray)n=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,n]of e)t.set(deepClone(r,a),deepClone(n,{...a,parent:e}));n=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));n=t}else if("Date"===r&&a.cloneDate)n=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;n=new RegExp(t.source,t.flags)}else n=e,o=!1;return a.onAfterClone?.({output:n,input:e,type:r,cloned:o,parent:a.parent}),n},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:n={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const o={};for(let s of a)o[s]=function(...a){const o={},l=e.length;switch(s){case"push":case"unshift":o.addedItems=[...a];break;case"pop":o.poppedItem=e[l-1];break;case"shift":o.shiftedItem=e[0];break;case"splice":const[t,r]=a,n=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-n:r;o.deletedItems=e.slice(n,n+s);break;case"sort":case"reverse":o.oldSnapshot=[...e];break;case"fill":case"copyWithin":const i=a[1]||0,c=void 0===a[2]?l:a[2];o.oldItems=e.slice(i,c),o.start=i,o.end=c}t?.(o);const i=Array.prototype[s].apply(e,a),c={value:i,key:s,args:a,context:o,target:e,...n};return r?.(c),i};return o},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],n=getDataType(e),o=n.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=o.includes("html")?"element":o;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,n)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return n},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,n=e.base36;return`${t?t+"-":""}${Date.now()}${n?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:n={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)setMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:n={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)mapMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let n,o,s=getDataType(e),l=getDataType(t),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(o=deepMergeObjects(e,t,a),n="Object"):"Array"===s&&"Array"===l?(o=deepMergeArrays(e,t,a),n="Array"):"Set"===s&&"Set"===l?(o=deepMergeSets(e,t,a),n="Set"):"Map"===s&&"Map"===l?(o=deepMergeMaps(e,t,a),n="Map"):(i=!1,o=e),a?.onAfterMerge?.({result:o,target:e,source:t,targetType:s,sourceType:l,mergeType:n,parent:r.parent}),{result:o,flag:i,mergeType:n}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),n=getDataType(t);if("Object"!==a||"Object"!==n)return e;const o=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=o.targetClone?shallowCopy(e):e;for(let e in t){const a=s[e],n=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(a,n,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=n;else{let t=o.useEnable?mergeEnableObject(a,n):n;a!==t&&null===t?"ignore"===o.nullBehavior||("delete"===o.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):a!==t&&void 0===t?"ignore"===o.undefinedBehavior||("delete"===o.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=n):s[e]=n}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&o.inheritMissing&&(s[e]=n)}if(o.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),n=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=n.length));e++){smartMerger(n[e],t[e],{...a,parent:n}).flag||(n[e]=t[e])}else"concat"===a.dataMode||(n.length=0),n.push(...t);return n},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Map([...e]):e;for(const[e,o]of t.entries())if(n.has(e)){const t=n.get(e),r=o,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&n.set(e,s.result):n.set(e,r)}else r.inheritMissing&&n.set(e,o);return n},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...n],r=[...t],o=smartMerger(e,r,a);n.clear();for(let e of o.result)n.add(e)}else if("concat"===a.dataMode)for(let e of t)n.add(e);else{n.clear();for(let e of t)n.add(e)}return n};return smartMerger(e,t,a).result},getEl=(e,t=document.body)=>{let r=getDataType(e),a=getDataType(t),n=a.includes("HTML")||"ShadowRoot"===a?t:document.querySelector(t),o=n&&n instanceof HTMLTemplateElement?n.content:n,s=null;if(e)if(r.includes("HTML"))s=e;else if("String"===r)try{s=(o||document).querySelector(e.trim())}catch{s=null}return s},isEmpty=e=>{let t,r=getDataType(e);return t=!e||("Object"===r?0===Object.keys(e).length:"Array"===r?""===e.join(""):"Function"===r?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===r?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===r||"Map"===r?0===e.size:"Date"===r?isNaN(e.getTime()):"RegExp"===r?""===e.source:"ArrayBuffer"===r?0===e.byteLength:"NodeList"===r||"HTMLCollection"===r||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===r||e instanceof Error?""===e.message:!(!r.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(r))&&0===e.length),t},getEls=(e,t=document.body)=>{let r=getDataType(e),a=getEl(t),n=a&&a instanceof HTMLTemplateElement?a.content:a||document,o=[];return isEmpty(e)?o:(r.includes("HTML")?o.push(e):"String"===r?o=(e=e.trim()).split(",").map(e=>[...n.querySelectorAll(e)]).flat():"Array"===r&&(o=e.map(e=>getEl(e,a))),o.filter(Boolean))},createEl=(e,t,r)=>{let a=(e=e||"div").toUpperCase().trim(),n=document.createElement(a),o=getDataType(t);if(t&&"Object"===o)for(let e in t)t.hasOwnProperty(e)&&n.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let r=getDataType(t);if("TEMPLATE"===a)e.innerHTML=t.toString();else if("Array"===r&&t.length>0)for(let r of t){if(getDataType(r).includes("HTML"))e.appendChild(r);else{let t=createEl(r.name,r.attrs,r.content);t&&e.appendChild(t)}}else if(r.includes("HTML"))e.appendChild(t);else if("String"===r&&t.trim().startsWith("#")&&t.trim().length>1){let r=getEl(t);if(!r)return;"TEMPLATE"===r.nodeName?e.appendChild(r.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",r.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(n,r),n},svgToBase64=e=>`data:image/svg+xml;charset=utf-8,${encodeURIComponent(e).replace(/'/g,"%27").replace(/"/g,"%22")}`,utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:getEls,createEl:createEl,svgToBase64:svgToBase64};export{utils as default};
15
+ const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let n,o=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const n of r)t[n]=deepClone(e[n],{...a,parent:e});n=t}else if("Array"===r&&a.cloneArray)n=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,n]of e)t.set(deepClone(r,a),deepClone(n,{...a,parent:e}));n=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));n=t}else if("Date"===r&&a.cloneDate)n=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;n=new RegExp(t.source,t.flags)}else n=e,o=!1;return a.onAfterClone?.({output:n,input:e,type:r,cloned:o,parent:a.parent}),n},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:n={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const o={};for(let s of a)o[s]=function(...a){const o={},l=e.length;switch(s){case"push":case"unshift":o.addedItems=[...a];break;case"pop":o.poppedItem=e[l-1];break;case"shift":o.shiftedItem=e[0];break;case"splice":const[t,r]=a,n=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-n:r;o.deletedItems=e.slice(n,n+s);break;case"sort":case"reverse":o.oldSnapshot=[...e];break;case"fill":case"copyWithin":const i=a[1]||0,c=void 0===a[2]?l:a[2];o.oldItems=e.slice(i,c),o.start=i,o.end=c}t?.(o);const i=Array.prototype[s].apply(e,a),c={value:i,key:s,args:a,context:o,target:e,...n};return r?.(c),i};return o},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],n=getDataType(e),o=n.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=o.includes("html")?"element":o;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,n)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return n},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,n=e.base36;return`${t?t+"-":""}${Date.now()}${n?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:n={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)setMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:n={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)mapMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let n,o,s=getDataType(e),l=getDataType(t),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(o=deepMergeObjects(e,t,a),n="Object"):"Array"===s&&"Array"===l?(o=deepMergeArrays(e,t,a),n="Array"):"Set"===s&&"Set"===l?(o=deepMergeSets(e,t,a),n="Set"):"Map"===s&&"Map"===l?(o=deepMergeMaps(e,t,a),n="Map"):(i=!1,o=e),a?.onAfterMerge?.({result:o,target:e,source:t,targetType:s,sourceType:l,mergeType:n,parent:r.parent}),{result:o,flag:i,mergeType:n}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),n=getDataType(t);if("Object"!==a||"Object"!==n)return e;const o=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=o.targetClone?shallowCopy(e):e;for(let e in t){const a=s[e],n=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(a,n,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=n;else{let t=o.useEnable?mergeEnableObject(a,n):n;a!==t&&null===t?"ignore"===o.nullBehavior||("delete"===o.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):a!==t&&void 0===t?"ignore"===o.undefinedBehavior||("delete"===o.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=n):s[e]=n}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&o.inheritMissing&&(s[e]=n)}if(o.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),n=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=n.length));e++){smartMerger(n[e],t[e],{...a,parent:n}).flag||(n[e]=t[e])}else"concat"===a.dataMode||(n.length=0),n.push(...t);return n},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Map([...e]):e;for(const[e,o]of t.entries())if(n.has(e)){const t=n.get(e),r=o,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&n.set(e,s.result):n.set(e,r)}else r.inheritMissing&&n.set(e,o);return n},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...n],r=[...t],o=smartMerger(e,r,a);n.clear();for(let e of o.result)n.add(e)}else if("concat"===a.dataMode)for(let e of t)n.add(e);else{n.clear();for(let e of t)n.add(e)}return n};return smartMerger(e,t,a).result},getEl=(e,t=document.body)=>{let r=getDataType(e),a=getDataType(t),n=a.includes("HTML")||"ShadowRoot"===a?t:document.querySelector(t),o=n&&n instanceof HTMLTemplateElement?n.content:n,s=null;if(e)if(r.includes("HTML"))s=e;else if("String"===r)try{s=(o||document).querySelector(e.trim())}catch{s=null}return s},isEmpty=e=>{let t,r=getDataType(e);return t=!e||("Object"===r?0===Object.keys(e).length:"Array"===r?""===e.join(""):"Function"===r?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===r?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===r||"Map"===r?0===e.size:"Date"===r?isNaN(e.getTime()):"RegExp"===r?""===e.source:"ArrayBuffer"===r?0===e.byteLength:"NodeList"===r||"HTMLCollection"===r||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===r||e instanceof Error?""===e.message:!(!r.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(r))&&0===e.length),t},getEls=(e,t=document.body)=>{let r=getDataType(e),a=getEl(t),n=a&&a instanceof HTMLTemplateElement?a.content:a||document,o=[];return isEmpty(e)?o:(r.includes("HTML")?o.push(e):"String"===r?o=(e=e.trim()).split(",").map(e=>[...n.querySelectorAll(e)]).flat():"Array"===r&&(o=e.map(e=>getEl(e,a))),o.filter(Boolean))},createEl=(e,t,r)=>{let a=(e=e||"div").toUpperCase().trim(),n=document.createElement(a),o=getDataType(t);if(t&&"Object"===o)for(let e in t)t.hasOwnProperty(e)&&n.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let r=getDataType(t);if("TEMPLATE"===a)e.innerHTML=t.toString();else if("Array"===r&&t.length>0)for(let r of t){if(getDataType(r).includes("HTML"))e.appendChild(r);else{let t=createEl(r.name,r.attrs,r.content);t&&e.appendChild(t)}}else if(r.includes("HTML"))e.appendChild(t);else if("String"===r&&t.trim().startsWith("#")&&t.trim().length>1){let r=getEl(t);if(!r)return;"TEMPLATE"===r.nodeName?e.appendChild(r.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",r.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(n,r),n},getSvgUri=e=>`data:image/svg+xml;utf8,${e.replace(/\n/g,"").replace(/\s+/g," ").trim().replace(/%/g,"%25").replace(/#/g,"%23").replace(/{/g,"%7B").replace(/}/g,"%7D").replace(/</g,"%3C").replace(/>/g,"%3E")}`,fileToBase64=e=>new Promise((t,r)=>{const a=new FileReader;a.onload=()=>{"string"==typeof a.result?t(a.result):r(new Error("FileReader result is not a string"))},a.onerror=()=>{r(a.error||new Error("Unknown error occurred during file reading"))},a.readAsDataURL(e)}),utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:getEls,createEl:createEl,getSvgUri:getSvgUri,fileToBase64:fileToBase64};export{utils as default};
package/dist/utils.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2026-1-6 21:54:24
3
+ * @since Last modified: 2026-1-7 8:57:42
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.22
5
+ * @version 0.0.23
6
6
  * @author AXUI development team <3217728223@qq.com>
7
7
  * @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.
8
8
  * @see {@link https://www.axui.cn|Official website}
@@ -905,12 +905,50 @@
905
905
  return rootEl;
906
906
  };
907
907
 
908
- const svgToBase64 = (svgString) => {
909
- // 1. This method provides the best compatibility (escaping special characters)
910
- const encoded = encodeURIComponent(svgString)
911
- .replace(/'/g, "%27")
912
- .replace(/"/g, "%22");
913
- return `data:image/svg+xml;charset=utf-8,${encoded}`;
908
+ const getSvgUri = (svgString) => {
909
+ // 1. Minify the SVG: Remove line breaks and collapse multiple spaces
910
+ // to ensure the resulting URI is a single, clean line.
911
+ const cleanedSvg = svgString
912
+ .replace(/\n/g, '')
913
+ .replace(/\s+/g, ' ')
914
+ .trim();
915
+ // 2. Character Encoding:
916
+ // We escape specific characters that have special meanings in URLs or
917
+ // can break CSS parser logic (especially when used in background-image: url()).
918
+ // - '#' (Hash) is escaped to '%23' because it's a URL fragment identifier.
919
+ // - '%' (Percent) is escaped to '%25' as it is the escape character itself.
920
+ // - '<' and '>' are escaped to '%3C' and '%3E' for URL safety.
921
+ // - '{' and '}' are escaped to '%7B' and '%7D' to avoid conflicts with CSS block syntax.
922
+ const encoded = cleanedSvg
923
+ .replace(/%/g, '%25')
924
+ .replace(/#/g, '%23')
925
+ .replace(/{/g, '%7B')
926
+ .replace(/}/g, '%7D')
927
+ .replace(/</g, '%3C')
928
+ .replace(/>/g, '%3E');
929
+ return `data:image/svg+xml;utf8,${encoded}`;
930
+ };
931
+
932
+ const fileToBase64 = (file) => {
933
+ return new Promise((resolve, reject) => {
934
+ const reader = new FileReader();
935
+ // Triggered when the read operation is successfully completed
936
+ reader.onload = () => {
937
+ // When using readAsDataURL, the result is guaranteed to be a string
938
+ if (typeof reader.result === 'string') {
939
+ resolve(reader.result);
940
+ }
941
+ else {
942
+ reject(new Error('FileReader result is not a string'));
943
+ }
944
+ };
945
+ // Triggered when the read operation encounters an error
946
+ reader.onerror = () => {
947
+ reject(reader.error || new Error('Unknown error occurred during file reading'));
948
+ };
949
+ // Initiates the reading process to convert the file into a Data URL
950
+ reader.readAsDataURL(file);
951
+ });
914
952
  };
915
953
 
916
954
  const utils = {
@@ -934,7 +972,8 @@
934
972
  getEl,
935
973
  getEls,
936
974
  createEl,
937
- svgToBase64,
975
+ getSvgUri,
976
+ fileToBase64,
938
977
  };
939
978
 
940
979
  return utils;
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2026-1-6 21:54:24
2
+ * @since Last modified: 2026-1-7 8:57:42
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.22
4
+ * @version 0.0.23
5
5
  * @author AXUI development team <3217728223@qq.com>
6
6
  * @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.
7
7
  * @see {@link https://www.axui.cn|Official website}
@@ -12,4 +12,4 @@
12
12
  * @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.
13
13
  * @license MIT license
14
14
  */
15
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t()}(this,function(){"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),n=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(n.interceptor&&"function"==typeof n.interceptor){let t=n.interceptor({input:e,type:r,parent:n.parent});if(t)return t}n.onBeforeClone?.({input:e,type:r,parent:n.parent});let o,a=!0;if("Object"===r&&n.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],n);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...n,parent:e});o=t}else if("Array"===r&&n.cloneArray)o=e.map(t=>deepClone(t,{...n,parent:e}));else if("Map"===r&&n.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,n),deepClone(o,{...n,parent:e}));o=t}else if("Set"===r&&n.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...n,parent:e}));o=t}else if("Date"===r&&n.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&n.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,a=!1;return n.onAfterClone?.({output:o,input:e,type:r,cloned:a,parent:n.parent}),o},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},e=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],t=["add","delete","clear"],r=["set","delete","clear"],copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},getEl=(e,t=document.body)=>{let r=getDataType(e),n=getDataType(t),o=n.includes("HTML")||"ShadowRoot"===n?t:document.querySelector(t),a=o&&o instanceof HTMLTemplateElement?o.content:o,s=null;if(e)if(r.includes("HTML"))s=e;else if("String"===r)try{s=(a||document).querySelector(e.trim())}catch{s=null}return s},createEl=(e,t,r)=>{let n=(e=e||"div").toUpperCase().trim(),o=document.createElement(n),a=getDataType(t);if(t&&"Object"===a)for(let e in t)t.hasOwnProperty(e)&&o.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let r=getDataType(t);if("TEMPLATE"===n)e.innerHTML=t.toString();else if("Array"===r&&t.length>0)for(let r of t){if(getDataType(r).includes("HTML"))e.appendChild(r);else{let t=createEl(r.name,r.attrs,r.content);t&&e.appendChild(t)}}else if(r.includes("HTML"))e.appendChild(t);else if("String"===r&&t.trim().startsWith("#")&&t.trim().length>1){let r=getEl(t);if(!r)return;"TEMPLATE"===r.nodeName?e.appendChild(r.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",r.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(o,r),o};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let n=Array.isArray(t)?t:[t],o=getDataType(e),a=o.toLowerCase(),s=n.map(e=>e.toLowerCase()),i=a.includes("html")?"element":a;if(r)try{if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`)}catch(e){r(e,o)}else if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`);return o},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:t,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o,props:a={}})=>{if(!Array.isArray(t))throw new TypeError("The 'target' parameter must be an array.");o&&!o?.length||(o=e);const s={};for(let e of o)s[e]=function(...o){const s={},i=t.length;switch(e){case"push":case"unshift":s.addedItems=[...o];break;case"pop":s.poppedItem=t[i-1];break;case"shift":s.shiftedItem=t[0];break;case"splice":const[e,r]=o,n=e<0?Math.max(i+e,0):Math.min(e,i),a=void 0===r?i-n:r;s.deletedItems=t.slice(n,n+a);break;case"sort":case"reverse":s.oldSnapshot=[...t];break;case"fill":case"copyWithin":const l=o[1]||0,c=void 0===o[2]?i:o[2];s.oldItems=t.slice(l,c),s.start=l,s.end=c}r?.(s);const l=Array.prototype[e].apply(t,o),c={value:l,key:e,args:o,context:s,target:t,...a};return n?.(c),l};return s},arrayMutableMethods:e,setMutableMethods:t,mapMutableMethods:r,wrapSetMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o=t,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=t=>function(...o){const s={};switch(t){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}r(s);const i=e[t].apply(e,o),l={method:t,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)t.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},wrapMapMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:n=()=>{},allowList:o=r,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=r=>function(...o){const s={};switch(r){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const i=e[r].apply(e,o),l={method:r,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)r.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},getUniqueId:(e={})=>{const t=e.prefix,r=e.suffix,n=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${n?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},deepMerge:(e,t,r={})=>{const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,n)=>{let o,a,s=getDataType(e),i=getDataType(t),l=!0;if(n.interceptor&&"function"==typeof n.interceptor){let r=n.interceptor({target:e,source:t,targetType:s,sourceType:i,parent:n.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return n?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:i,parent:n.parent}),"Object"===s&&"Object"===i?(a=deepMergeObjects(e,t,n),o="Object"):"Array"===s&&"Array"===i?(a=deepMergeArrays(e,t,n),o="Array"):"Set"===s&&"Set"===i?(a=deepMergeSets(e,t,n),o="Set"):"Map"===s&&"Map"===i?(a=deepMergeMaps(e,t,n),o="Map"):(l=!1,a=e),n?.onAfterMerge?.({result:a,target:e,source:t,targetType:s,sourceType:i,mergeType:o,parent:r.parent}),{result:a,flag:l,mergeType:o}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let n=getDataType(e),o=getDataType(t);if("Object"!==n||"Object"!==o)return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=a.targetClone?shallowCopy(e):e;for(let e in t){const n=s[e],o=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(n,o,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=o;else{let t=a.useEnable?mergeEnableObject(n,o):o;n!==t&&null===t?"ignore"===a.nullBehavior||("delete"===a.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):n!==t&&void 0===t?"ignore"===a.undefinedBehavior||("delete"===a.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=o):s[e]=o}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&a.inheritMissing&&(s[e]=o)}if(a.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=n.targetClone?[...e]:e;if("replace"===n.dataMode)for(let e=0;e<t.length&&(n.inheritMissing||!(e>=o.length));e++){smartMerger(o[e],t[e],{...n,parent:o}).flag||(o[e]=t[e])}else"concat"===n.dataMode||(o.length=0),o.push(...t);return o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Map([...e]):e;for(const[e,a]of t.entries())if(o.has(e)){const t=o.get(e),r=a,s=smartMerger(t,r,n);s.flag?"Object"===s.mergeType&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,a);return o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Set(...e):e;if("replace"===n.dataMode){const e=[...o],r=[...t],a=smartMerger(e,r,n);o.clear();for(let e of a.result)o.add(e)}else if("concat"===n.dataMode)for(let e of t)o.add(e);else{o.clear();for(let e of t)o.add(e)}return o};return smartMerger(e,t,n).result},shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:(e,t=document.body)=>{let r=getDataType(e),n=getEl(t),o=n&&n instanceof HTMLTemplateElement?n.content:n||document,a=[];return(e=>{let t,r=getDataType(e);return t=!e||("Object"===r?0===Object.keys(e).length:"Array"===r?""===e.join(""):"Function"===r?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===r?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===r||"Map"===r?0===e.size:"Date"===r?isNaN(e.getTime()):"RegExp"===r?""===e.source:"ArrayBuffer"===r?0===e.byteLength:"NodeList"===r||"HTMLCollection"===r||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===r||e instanceof Error?""===e.message:!(!r.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(r))&&0===e.length),t})(e)?a:(r.includes("HTML")?a.push(e):"String"===r?a=(e=e.trim()).split(",").map(e=>[...o.querySelectorAll(e)]).flat():"Array"===r&&(a=e.map(e=>getEl(e,n))),a.filter(Boolean))},createEl:createEl,svgToBase64:e=>`data:image/svg+xml;charset=utf-8,${encodeURIComponent(e).replace(/'/g,"%27").replace(/"/g,"%22")}`}});
15
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t()}(this,function(){"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),n=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(n.interceptor&&"function"==typeof n.interceptor){let t=n.interceptor({input:e,type:r,parent:n.parent});if(t)return t}n.onBeforeClone?.({input:e,type:r,parent:n.parent});let o,a=!0;if("Object"===r&&n.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],n);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...n,parent:e});o=t}else if("Array"===r&&n.cloneArray)o=e.map(t=>deepClone(t,{...n,parent:e}));else if("Map"===r&&n.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,n),deepClone(o,{...n,parent:e}));o=t}else if("Set"===r&&n.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...n,parent:e}));o=t}else if("Date"===r&&n.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&n.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,a=!1;return n.onAfterClone?.({output:o,input:e,type:r,cloned:a,parent:n.parent}),o},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},e=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],t=["add","delete","clear"],r=["set","delete","clear"],copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},getEl=(e,t=document.body)=>{let r=getDataType(e),n=getDataType(t),o=n.includes("HTML")||"ShadowRoot"===n?t:document.querySelector(t),a=o&&o instanceof HTMLTemplateElement?o.content:o,s=null;if(e)if(r.includes("HTML"))s=e;else if("String"===r)try{s=(a||document).querySelector(e.trim())}catch{s=null}return s},createEl=(e,t,r)=>{let n=(e=e||"div").toUpperCase().trim(),o=document.createElement(n),a=getDataType(t);if(t&&"Object"===a)for(let e in t)t.hasOwnProperty(e)&&o.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let r=getDataType(t);if("TEMPLATE"===n)e.innerHTML=t.toString();else if("Array"===r&&t.length>0)for(let r of t){if(getDataType(r).includes("HTML"))e.appendChild(r);else{let t=createEl(r.name,r.attrs,r.content);t&&e.appendChild(t)}}else if(r.includes("HTML"))e.appendChild(t);else if("String"===r&&t.trim().startsWith("#")&&t.trim().length>1){let r=getEl(t);if(!r)return;"TEMPLATE"===r.nodeName?e.appendChild(r.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",r.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(o,r),o};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let n=Array.isArray(t)?t:[t],o=getDataType(e),a=o.toLowerCase(),s=n.map(e=>e.toLowerCase()),i=a.includes("html")?"element":a;if(r)try{if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`)}catch(e){r(e,o)}else if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`);return o},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:t,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o,props:a={}})=>{if(!Array.isArray(t))throw new TypeError("The 'target' parameter must be an array.");o&&!o?.length||(o=e);const s={};for(let e of o)s[e]=function(...o){const s={},i=t.length;switch(e){case"push":case"unshift":s.addedItems=[...o];break;case"pop":s.poppedItem=t[i-1];break;case"shift":s.shiftedItem=t[0];break;case"splice":const[e,r]=o,n=e<0?Math.max(i+e,0):Math.min(e,i),a=void 0===r?i-n:r;s.deletedItems=t.slice(n,n+a);break;case"sort":case"reverse":s.oldSnapshot=[...t];break;case"fill":case"copyWithin":const l=o[1]||0,c=void 0===o[2]?i:o[2];s.oldItems=t.slice(l,c),s.start=l,s.end=c}r?.(s);const l=Array.prototype[e].apply(t,o),c={value:l,key:e,args:o,context:s,target:t,...a};return n?.(c),l};return s},arrayMutableMethods:e,setMutableMethods:t,mapMutableMethods:r,wrapSetMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o=t,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=t=>function(...o){const s={};switch(t){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}r(s);const i=e[t].apply(e,o),l={method:t,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)t.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},wrapMapMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:n=()=>{},allowList:o=r,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=r=>function(...o){const s={};switch(r){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const i=e[r].apply(e,o),l={method:r,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)r.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},getUniqueId:(e={})=>{const t=e.prefix,r=e.suffix,n=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${n?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},deepMerge:(e,t,r={})=>{const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,n)=>{let o,a,s=getDataType(e),i=getDataType(t),l=!0;if(n.interceptor&&"function"==typeof n.interceptor){let r=n.interceptor({target:e,source:t,targetType:s,sourceType:i,parent:n.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return n?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:i,parent:n.parent}),"Object"===s&&"Object"===i?(a=deepMergeObjects(e,t,n),o="Object"):"Array"===s&&"Array"===i?(a=deepMergeArrays(e,t,n),o="Array"):"Set"===s&&"Set"===i?(a=deepMergeSets(e,t,n),o="Set"):"Map"===s&&"Map"===i?(a=deepMergeMaps(e,t,n),o="Map"):(l=!1,a=e),n?.onAfterMerge?.({result:a,target:e,source:t,targetType:s,sourceType:i,mergeType:o,parent:r.parent}),{result:a,flag:l,mergeType:o}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let n=getDataType(e),o=getDataType(t);if("Object"!==n||"Object"!==o)return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=a.targetClone?shallowCopy(e):e;for(let e in t){const n=s[e],o=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(n,o,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=o;else{let t=a.useEnable?mergeEnableObject(n,o):o;n!==t&&null===t?"ignore"===a.nullBehavior||("delete"===a.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):n!==t&&void 0===t?"ignore"===a.undefinedBehavior||("delete"===a.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=o):s[e]=o}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&a.inheritMissing&&(s[e]=o)}if(a.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=n.targetClone?[...e]:e;if("replace"===n.dataMode)for(let e=0;e<t.length&&(n.inheritMissing||!(e>=o.length));e++){smartMerger(o[e],t[e],{...n,parent:o}).flag||(o[e]=t[e])}else"concat"===n.dataMode||(o.length=0),o.push(...t);return o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Map([...e]):e;for(const[e,a]of t.entries())if(o.has(e)){const t=o.get(e),r=a,s=smartMerger(t,r,n);s.flag?"Object"===s.mergeType&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,a);return o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Set(...e):e;if("replace"===n.dataMode){const e=[...o],r=[...t],a=smartMerger(e,r,n);o.clear();for(let e of a.result)o.add(e)}else if("concat"===n.dataMode)for(let e of t)o.add(e);else{o.clear();for(let e of t)o.add(e)}return o};return smartMerger(e,t,n).result},shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:(e,t=document.body)=>{let r=getDataType(e),n=getEl(t),o=n&&n instanceof HTMLTemplateElement?n.content:n||document,a=[];return(e=>{let t,r=getDataType(e);return t=!e||("Object"===r?0===Object.keys(e).length:"Array"===r?""===e.join(""):"Function"===r?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===r?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===r||"Map"===r?0===e.size:"Date"===r?isNaN(e.getTime()):"RegExp"===r?""===e.source:"ArrayBuffer"===r?0===e.byteLength:"NodeList"===r||"HTMLCollection"===r||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===r||e instanceof Error?""===e.message:!(!r.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(r))&&0===e.length),t})(e)?a:(r.includes("HTML")?a.push(e):"String"===r?a=(e=e.trim()).split(",").map(e=>[...o.querySelectorAll(e)]).flat():"Array"===r&&(a=e.map(e=>getEl(e,n))),a.filter(Boolean))},createEl:createEl,getSvgUri:e=>`data:image/svg+xml;utf8,${e.replace(/\n/g,"").replace(/\s+/g," ").trim().replace(/%/g,"%25").replace(/#/g,"%23").replace(/{/g,"%7B").replace(/}/g,"%7D").replace(/</g,"%3C").replace(/>/g,"%3E")}`,fileToBase64:e=>new Promise((t,r)=>{const n=new FileReader;n.onload=()=>{"string"==typeof n.result?t(n.result):r(new Error("FileReader result is not a string"))},n.onerror=()=>{r(n.error||new Error("Unknown error occurred during file reading"))},n.readAsDataURL(e)})}});
package/dist.zip CHANGED
Binary file
package/modules.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Last modified: 2026/01/06 21:49:47
2
+ * Last modified: 2026/01/07 08:57:30
3
3
  */
4
4
  'use strict';
5
5
  import deepClone from './src/deepClone';
@@ -19,7 +19,8 @@ import copyObjectWithSymbol from './src/copyObjectWithSymbol';
19
19
  import getEl from './src/getEl';
20
20
  import getEls from './src/getEls';
21
21
  import createEl from './src/createEl';
22
- import { svgToBase64 } from './src/svgToBase64';
22
+ import getSvgUri from './src/getSvgUri';
23
+ import fileToBase64 from './src/fileToBase64';
23
24
  const utils = {
24
25
  //executeStr,
25
26
  getDataType,
@@ -41,6 +42,7 @@ const utils = {
41
42
  getEl,
42
43
  getEls,
43
44
  createEl,
44
- svgToBase64,
45
+ getSvgUri,
46
+ fileToBase64,
45
47
  };
46
48
  export default utils;
package/modules.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Last modified: 2026/01/06 21:49:47
2
+ * Last modified: 2026/01/07 08:57:30
3
3
  */
4
4
  'use strict'
5
5
  import deepClone from './src/deepClone';
@@ -27,7 +27,8 @@ import copyObjectWithSymbol from './src/copyObjectWithSymbol';
27
27
  import getEl from './src/getEl';
28
28
  import getEls from './src/getEls';
29
29
  import createEl from './src/createEl';
30
- import { svgToBase64 } from './src/svgToBase64';
30
+ import getSvgUri from './src/getSvgUri';
31
+ import fileToBase64 from './src/fileToBase64';
31
32
 
32
33
 
33
34
 
@@ -52,7 +53,8 @@ const utils = {
52
53
  getEl,
53
54
  getEls,
54
55
  createEl,
55
- svgToBase64,
56
+ getSvgUri,
57
+ fileToBase64,
56
58
 
57
59
  };
58
60
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codady/utils",
3
- "version": "0.0.22",
3
+ "version": "0.0.23",
4
4
  "author": "AXUI Development Team",
5
5
  "license": "MIT",
6
6
  "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.",
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @since Last modified: 2026/01/07 08:54:36
3
+ * Converts a File or Blob object into a Base64 encoded string (Data URI format).
4
+ * * @param file - The File or Blob object to be converted.
5
+ * @returns A promise that resolves to the Data URI string (e.g., "data:image/png;base64,...").
6
+ */
7
+ const fileToBase64 = (file) => {
8
+ return new Promise((resolve, reject) => {
9
+ const reader = new FileReader();
10
+ // Triggered when the read operation is successfully completed
11
+ reader.onload = () => {
12
+ // When using readAsDataURL, the result is guaranteed to be a string
13
+ if (typeof reader.result === 'string') {
14
+ resolve(reader.result);
15
+ }
16
+ else {
17
+ reject(new Error('FileReader result is not a string'));
18
+ }
19
+ };
20
+ // Triggered when the read operation encounters an error
21
+ reader.onerror = () => {
22
+ reject(reader.error || new Error('Unknown error occurred during file reading'));
23
+ };
24
+ // Initiates the reading process to convert the file into a Data URL
25
+ reader.readAsDataURL(file);
26
+ });
27
+ };
28
+ export default fileToBase64;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @since Last modified: 2026/01/07 08:54:36
3
+ * Converts a File or Blob object into a Base64 encoded string (Data URI format).
4
+ * * @param file - The File or Blob object to be converted.
5
+ * @returns A promise that resolves to the Data URI string (e.g., "data:image/png;base64,...").
6
+ */
7
+ const fileToBase64 = (file: File | Blob): Promise<string> => {
8
+ return new Promise((resolve, reject) => {
9
+ const reader = new FileReader();
10
+
11
+ // Triggered when the read operation is successfully completed
12
+ reader.onload = () => {
13
+ // When using readAsDataURL, the result is guaranteed to be a string
14
+ if (typeof reader.result === 'string') {
15
+ resolve(reader.result);
16
+ } else {
17
+ reject(new Error('FileReader result is not a string'));
18
+ }
19
+ };
20
+
21
+ // Triggered when the read operation encounters an error
22
+ reader.onerror = () => {
23
+ reject(reader.error || new Error('Unknown error occurred during file reading'));
24
+ };
25
+
26
+ // Initiates the reading process to convert the file into a Data URL
27
+ reader.readAsDataURL(file);
28
+ });
29
+ };
30
+
31
+ export default fileToBase64;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @since Last modified: 2026/01/07 08:53:59
3
+ * Converts a raw SVG string into a UTF-8 encoded Data URI.
4
+ * * Unlike Base64, this format keeps the SVG human-readable and
5
+ * is typically more space-efficient for text-based graphics.
6
+ * * @param svgString - The raw SVG source code to convert.
7
+ * @returns A formatted Data URI string (e.g., "data:image/svg+xml;utf8,...")
8
+ */
9
+ const getSvgUri = (svgString) => {
10
+ // 1. Minify the SVG: Remove line breaks and collapse multiple spaces
11
+ // to ensure the resulting URI is a single, clean line.
12
+ const cleanedSvg = svgString
13
+ .replace(/\n/g, '')
14
+ .replace(/\s+/g, ' ')
15
+ .trim();
16
+ // 2. Character Encoding:
17
+ // We escape specific characters that have special meanings in URLs or
18
+ // can break CSS parser logic (especially when used in background-image: url()).
19
+ // - '#' (Hash) is escaped to '%23' because it's a URL fragment identifier.
20
+ // - '%' (Percent) is escaped to '%25' as it is the escape character itself.
21
+ // - '<' and '>' are escaped to '%3C' and '%3E' for URL safety.
22
+ // - '{' and '}' are escaped to '%7B' and '%7D' to avoid conflicts with CSS block syntax.
23
+ const encoded = cleanedSvg
24
+ .replace(/%/g, '%25')
25
+ .replace(/#/g, '%23')
26
+ .replace(/{/g, '%7B')
27
+ .replace(/}/g, '%7D')
28
+ .replace(/</g, '%3C')
29
+ .replace(/>/g, '%3E');
30
+ return `data:image/svg+xml;utf8,${encoded}`;
31
+ };
32
+ export default getSvgUri;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @since Last modified: 2026/01/07 08:53:59
3
+ * Converts a raw SVG string into a UTF-8 encoded Data URI.
4
+ * * Unlike Base64, this format keeps the SVG human-readable and
5
+ * is typically more space-efficient for text-based graphics.
6
+ * * @param svgString - The raw SVG source code to convert.
7
+ * @returns A formatted Data URI string (e.g., "data:image/svg+xml;utf8,...")
8
+ */
9
+ const getSvgUri = (svgString: string): string => {
10
+ // 1. Minify the SVG: Remove line breaks and collapse multiple spaces
11
+ // to ensure the resulting URI is a single, clean line.
12
+ const cleanedSvg = svgString
13
+ .replace(/\n/g, '')
14
+ .replace(/\s+/g, ' ')
15
+ .trim();
16
+
17
+ // 2. Character Encoding:
18
+ // We escape specific characters that have special meanings in URLs or
19
+ // can break CSS parser logic (especially when used in background-image: url()).
20
+ // - '#' (Hash) is escaped to '%23' because it's a URL fragment identifier.
21
+ // - '%' (Percent) is escaped to '%25' as it is the escape character itself.
22
+ // - '<' and '>' are escaped to '%3C' and '%3E' for URL safety.
23
+ // - '{' and '}' are escaped to '%7B' and '%7D' to avoid conflicts with CSS block syntax.
24
+ const encoded = cleanedSvg
25
+ .replace(/%/g, '%25')
26
+ .replace(/#/g, '%23')
27
+ .replace(/{/g, '%7B')
28
+ .replace(/}/g, '%7D')
29
+ .replace(/</g, '%3C')
30
+ .replace(/>/g, '%3E');
31
+
32
+ return `data:image/svg+xml;utf8,${encoded}`;
33
+ };
34
+
35
+ export default getSvgUri;
@@ -1,22 +0,0 @@
1
- /**
2
- * @since Last modified: 2026/01/06 21:45:02
3
- * Converts an SVG string to a Base64 or URL-encoded format for use in `src` or background image.
4
- * This function ensures the SVG string is properly encoded to be safely used as a data URL.
5
- *
6
- * @param {string} svgString - The SVG string to be encoded.
7
- * @returns {string} - A data URL that can be used in `src` or as a background image, formatted as `data:image/svg+xml;charset=utf-8,`.
8
- *
9
- * @since Last modified: 2026/01/06 21:43:33
10
- *
11
- * Note:
12
- * - The function first URI-encodes the input string to make sure special characters are escaped.
13
- * - It replaces single quotes (') and double quotes (") with their respective URL-encoded forms (`%27` and `%22`) to prevent any potential issues in the URL.
14
- * - This approach provides better compatibility when embedding the SVG directly in HTML, CSS, or JavaScript.
15
- */
16
- export const svgToBase64 = (svgString) => {
17
- // 1. This method provides the best compatibility (escaping special characters)
18
- const encoded = encodeURIComponent(svgString)
19
- .replace(/'/g, "%27")
20
- .replace(/"/g, "%22");
21
- return `data:image/svg+xml;charset=utf-8,${encoded}`;
22
- };
@@ -1,22 +0,0 @@
1
- /**
2
- * @since Last modified: 2026/01/06 21:45:02
3
- * Converts an SVG string to a Base64 or URL-encoded format for use in `src` or background image.
4
- * This function ensures the SVG string is properly encoded to be safely used as a data URL.
5
- *
6
- * @param {string} svgString - The SVG string to be encoded.
7
- * @returns {string} - A data URL that can be used in `src` or as a background image, formatted as `data:image/svg+xml;charset=utf-8,`.
8
- *
9
- * @since Last modified: 2026/01/06 21:43:33
10
- *
11
- * Note:
12
- * - The function first URI-encodes the input string to make sure special characters are escaped.
13
- * - It replaces single quotes (') and double quotes (") with their respective URL-encoded forms (`%27` and `%22`) to prevent any potential issues in the URL.
14
- * - This approach provides better compatibility when embedding the SVG directly in HTML, CSS, or JavaScript.
15
- */
16
- export const svgToBase64 = (svgString: string):string => {
17
- // 1. This method provides the best compatibility (escaping special characters)
18
- const encoded = encodeURIComponent(svgString)
19
- .replace(/'/g, "%27")
20
- .replace(/"/g, "%22");
21
- return `data:image/svg+xml;charset=utf-8,${encoded}`;
22
- };