@codady/utils 0.0.23 → 0.0.24
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 +4 -4
- package/dist/utils.cjs.js +128 -2
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +128 -2
- package/dist/utils.esm.min.js +3 -3
- package/dist/utils.umd.js +128 -2
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/modules.js +21 -1
- package/modules.ts +22 -1
- package/package.json +1 -1
- package/src/addClasses.js +41 -0
- package/src/addClasses.ts +42 -0
- package/src/alias.js +2 -0
- package/src/alias.ts +2 -0
- package/src/classes.js +114 -0
- package/src/classes.ts +140 -0
- package/src/comma.js +2 -0
- package/src/comma.ts +2 -0
- package/src/createTools.js +79 -0
- package/src/createTools.ts +129 -0
- package/src/getClasses.js +16 -0
- package/src/getClasses.ts +20 -0
- package/src/hasClasses.js +36 -0
- package/src/hasClasses.ts +39 -0
- package/src/namespace.js +2 -0
- package/src/namespace.ts +2 -0
- package/src/parseClasses.js +34 -0
- package/src/parseClasses.ts +39 -0
- package/src/removeClasses.js +44 -0
- package/src/removeClasses.ts +47 -0
- package/src/space.js +2 -0
- package/src/space.ts +2 -0
- package/src/trim.js +41 -0
- package/src/trim.ts +44 -0
package/dist/utils.umd.min.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @since Last modified: 2026-1-7
|
|
2
|
+
* @since Last modified: 2026-1-7 13:47:29
|
|
3
3
|
* @name Utils for web front-end.
|
|
4
|
-
* @version 0.0.
|
|
4
|
+
* @version 0.0.24
|
|
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,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)})}});
|
|
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 a,o=!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 a of r)t[a]=deepClone(e[a],{...n,parent:e});a=t}else if("Array"===r&&n.cloneArray)a=e.map(t=>deepClone(t,{...n,parent:e}));else if("Map"===r&&n.cloneMap){const t=new Map;for(const[r,a]of e)t.set(deepClone(r,n),deepClone(a,{...n,parent:e}));a=t}else if("Set"===r&&n.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...n,parent:e}));a=t}else if("Date"===r&&n.cloneDate)a=new Date(e.getTime());else if("RegExp"===r&&n.cloneRegex){const t=e;a=new RegExp(t.source,t.flags)}else a=e,o=!1;return n.onAfterClone?.({output:a,input:e,type:r,cloned:o,parent:n.parent}),a},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),a=n.includes("HTML")||"ShadowRoot"===n?t:document.querySelector(t),o=a&&a instanceof HTMLTemplateElement?a.content:a,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},createEl=(e,t,r)=>{let n=(e=e||"div").toUpperCase().trim(),a=document.createElement(n),o=getDataType(t);if(t&&"Object"===o)for(let e in t)t.hasOwnProperty(e)&&a.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)})(a,r),a},n="rep",trim=(e,t="global")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses=e=>{let t,r=[];return Array.isArray(e)?r=e.filter(e=>e&&"string"==typeof e):(t=(e=trim(e)).includes(",")?",":" ",r=e.split(t)),r.map(e=>trim(e,"global")).filter(Boolean)},addClasses=(e,t,r)=>{const n=getEl(e),a=parseClasses(t);n&&0!==a.length&&a.forEach(e=>{let t;r?(t=r(e),!0===t?n.classList.add(e):"string"==typeof t&&t&&n.classList.add(t)):n.classList.add(e)})};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let n=Array.isArray(t)?t:[t],a=getDataType(e),o=a.toLowerCase(),s=n.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,a)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return a},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:t,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:a,props:o={}})=>{if(!Array.isArray(t))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=e);const s={};for(let e of a)s[e]=function(...a){const s={},l=t.length;switch(e){case"push":case"unshift":s.addedItems=[...a];break;case"pop":s.poppedItem=t[l-1];break;case"shift":s.shiftedItem=t[0];break;case"splice":const[e,r]=a,n=e<0?Math.max(l+e,0):Math.min(e,l),o=void 0===r?l-n:r;s.deletedItems=t.slice(n,n+o);break;case"sort":case"reverse":s.oldSnapshot=[...t];break;case"fill":case"copyWithin":const i=a[1]||0,c=void 0===a[2]?l:a[2];s.oldItems=t.slice(i,c),s.start=i,s.end=c}r?.(s);const i=Array.prototype[e].apply(t,a),c={value:i,key:e,args:a,context:s,target:t,...o};return n?.(c),i};return s},arrayMutableMethods:e,setMutableMethods:t,mapMutableMethods:r,wrapSetMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:a=t,props:o={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=t=>function(...a){const s={};switch(t){case"add":{const[t]=a;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=a;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 l=e[t].apply(e,a),i={method:t,result:l,args:a,context:s,target:e,...o};return n(i),l};for(const e of a)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:a=r,props:o={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=r=>function(...a){const s={};switch(r){case"set":{const[t,r]=a;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]=a;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[r].apply(e,a),i={method:r,result:l,args:a,context:s,target:e,...o};return n(i),l};for(const e of a)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,a=e.base36;return`${t?t+"-":""}${Date.now()}${a?"-"+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 a,o,s=getDataType(e),l=getDataType(t),i=!0;if(n.interceptor&&"function"==typeof n.interceptor){let r=n.interceptor({target:e,source:t,targetType:s,sourceType:l,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:l,parent:n.parent}),"Object"===s&&"Object"===l?(o=deepMergeObjects(e,t,n),a="Object"):"Array"===s&&"Array"===l?(o=deepMergeArrays(e,t,n),a="Array"):"Set"===s&&"Set"===l?(o=deepMergeSets(e,t,n),a="Set"):"Map"===s&&"Map"===l?(o=deepMergeMaps(e,t,n),a="Map"):(i=!1,o=e),n?.onAfterMerge?.({result:o,target:e,source:t,targetType:s,sourceType:l,mergeType:a,parent:r.parent}),{result:o,flag:i,mergeType:a}},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),a=getDataType(t);if("Object"!==n||"Object"!==a)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 n=s[e],a=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(n,a,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=a;else{let t=o.useEnable?mergeEnableObject(n,a):a;n!==t&&null===t?"ignore"===o.nullBehavior||("delete"===o.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):n!==t&&void 0===t?"ignore"===o.undefinedBehavior||("delete"===o.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=a):s[e]=a}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&o.inheritMissing&&(s[e]=a)}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 n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),a=n.targetClone?[...e]:e;if("replace"===n.dataMode)for(let e=0;e<t.length&&(n.inheritMissing||!(e>=a.length));e++){smartMerger(a[e],t[e],{...n,parent:a}).flag||(a[e]=t[e])}else"concat"===n.dataMode||(a.length=0),a.push(...t);return a},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),a=n.targetClone?new Map([...e]):e;for(const[e,o]of t.entries())if(a.has(e)){const t=a.get(e),r=o,s=smartMerger(t,r,n);s.flag?"Object"===s.mergeType&&a.set(e,s.result):a.set(e,r)}else r.inheritMissing&&a.set(e,o);return a},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),a=n.targetClone?new Set(...e):e;if("replace"===n.dataMode){const e=[...a],r=[...t],o=smartMerger(e,r,n);a.clear();for(let e of o.result)a.add(e)}else if("concat"===n.dataMode)for(let e of t)a.add(e);else{a.clear();for(let e of t)a.add(e)}return a};return smartMerger(e,t,n).result},shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:(e,t=document.body)=>{let r=getDataType(e),n=getEl(t),a=n&&n instanceof HTMLTemplateElement?n.content:n||document,o=[];return isEmpty(e)?o:(r.includes("HTML")?o.push(e):"String"===r?o=(e=e.trim()).split(",").map(e=>[...a.querySelectorAll(e)]).flat():"Array"===r&&(o=e.map(e=>getEl(e,n))),o.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)}),NAMESPACE:"ax",ALIAS:n,COMMA:",",SPACE:" ",trim:trim,parseClasses:parseClasses,getClasses:e=>{let t=getEl(e);return t?parseClasses(t.getAttribute("class")||""):[]},addClasses:addClasses,removeClasses:(e,t,r)=>{const n=getEl(e),a=parseClasses(t);n&&0!==a.length&&a.forEach(e=>{let t;r?(t=r(e),!0===t?n.classList.remove(e):"string"==typeof t&&t&&n.classList.remove(t)):n.classList.remove(e)})},createTools:e=>{const t=createEl("span",{class:"ax-box-tools"}),renderFn=e=>{const t={},r=e.extendable?`<i ${n}="arrow"></i>`:"",a=(e.icon?`<i ${n}="icon">${e.icon}</i>`:"")+(e.disk?`<i ${n}="disk"><img src="${e.disk}"/></i>`:"")+(e.cube?`<i ${n}="cube"><img src="${e.cube}"/></i>`:"")+(e.image?`<i ${n}="image"><img src="${e.image}"/></i>`:"")+(e.label?`<i ${n}="label">${e.label}</i>`:"")+r;e.title&&(t.title=e.title),e.focusable&&(t.tabindex=1),e.wrapEl=createEl(e.nodeName||"span",Object.assign(t,e.attrs),a),e.iconEl=e.wrapEl.querySelector(`[${n}="icon"]`),e.cubeEl=e.wrapEl.querySelector(`[${n}="cube"]`),e.diskEl=e.wrapEl.querySelector(`[${n}="disk"]`),e.imageEl=e.wrapEl.querySelector(`[${n}="image"]`),e.labelEl=e.wrapEl.querySelector(`[${n}="label"]`),!isEmpty(e.classes)&&addClasses(e.wrapEl,e.classes),!isEmpty(e.styles)&&(e.wrapEl.style.cssText+=e.styles)};for(let r of e)renderFn(r),t.appendChild(r.wrapEl),r?.action?.(r);return t}}});
|
package/dist.zip
CHANGED
|
Binary file
|
package/modules.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Last modified: 2026/01/07
|
|
2
|
+
* Last modified: 2026/01/07 13:47:21
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
import deepClone from './src/deepClone';
|
|
@@ -21,6 +21,16 @@ import getEls from './src/getEls';
|
|
|
21
21
|
import createEl from './src/createEl';
|
|
22
22
|
import getSvgUri from './src/getSvgUri';
|
|
23
23
|
import fileToBase64 from './src/fileToBase64';
|
|
24
|
+
import NAMESPACE from './src/namespace';
|
|
25
|
+
import ALIAS from './src/alias';
|
|
26
|
+
import COMMA from './src/comma';
|
|
27
|
+
import SPACE from './src/space';
|
|
28
|
+
import trim from './src/trim';
|
|
29
|
+
import parseClasses from './src/parseClasses';
|
|
30
|
+
import createTools from './src/createTools';
|
|
31
|
+
import getClasses from './src/getClasses';
|
|
32
|
+
import addClasses from './src/addClasses';
|
|
33
|
+
import removeClasses from './src/removeClasses';
|
|
24
34
|
const utils = {
|
|
25
35
|
//executeStr,
|
|
26
36
|
getDataType,
|
|
@@ -44,5 +54,15 @@ const utils = {
|
|
|
44
54
|
createEl,
|
|
45
55
|
getSvgUri,
|
|
46
56
|
fileToBase64,
|
|
57
|
+
NAMESPACE,
|
|
58
|
+
ALIAS,
|
|
59
|
+
COMMA,
|
|
60
|
+
SPACE,
|
|
61
|
+
trim,
|
|
62
|
+
parseClasses,
|
|
63
|
+
getClasses,
|
|
64
|
+
addClasses,
|
|
65
|
+
removeClasses,
|
|
66
|
+
createTools,
|
|
47
67
|
};
|
|
48
68
|
export default utils;
|
package/modules.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Last modified: 2026/01/07
|
|
2
|
+
* Last modified: 2026/01/07 13:47:21
|
|
3
3
|
*/
|
|
4
4
|
'use strict'
|
|
5
5
|
import deepClone from './src/deepClone';
|
|
@@ -29,6 +29,17 @@ import getEls from './src/getEls';
|
|
|
29
29
|
import createEl from './src/createEl';
|
|
30
30
|
import getSvgUri from './src/getSvgUri';
|
|
31
31
|
import fileToBase64 from './src/fileToBase64';
|
|
32
|
+
import NAMESPACE from './src/namespace';
|
|
33
|
+
import ALIAS from './src/alias';
|
|
34
|
+
import COMMA from './src/comma';
|
|
35
|
+
import SPACE from './src/space';
|
|
36
|
+
import trim from './src/trim';
|
|
37
|
+
import parseClasses from './src/parseClasses';
|
|
38
|
+
import classes from './src/classes';
|
|
39
|
+
import createTools from './src/createTools';
|
|
40
|
+
import getClasses from './src/getClasses';
|
|
41
|
+
import addClasses from './src/addClasses';
|
|
42
|
+
import removeClasses from './src/removeClasses';
|
|
32
43
|
|
|
33
44
|
|
|
34
45
|
|
|
@@ -55,6 +66,16 @@ const utils = {
|
|
|
55
66
|
createEl,
|
|
56
67
|
getSvgUri,
|
|
57
68
|
fileToBase64,
|
|
69
|
+
NAMESPACE,
|
|
70
|
+
ALIAS,
|
|
71
|
+
COMMA,
|
|
72
|
+
SPACE,
|
|
73
|
+
trim,
|
|
74
|
+
parseClasses,
|
|
75
|
+
getClasses,
|
|
76
|
+
addClasses,
|
|
77
|
+
removeClasses,
|
|
78
|
+
createTools,
|
|
58
79
|
|
|
59
80
|
};
|
|
60
81
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codady/utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.24",
|
|
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,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/01/07 12:04:57
|
|
3
|
+
* @namespace addClasses
|
|
4
|
+
* @description Adds one or more CSS classes to a DOM element. This function can add a list of class names
|
|
5
|
+
* either passed as a space/comma-separated string or an array of strings.
|
|
6
|
+
* It also supports an optional `intercept` callback to modify or intercept the class addition.
|
|
7
|
+
* @param {string | Node | null} target - The target DOM element, Node, or CSS selector to which the classes will be added.
|
|
8
|
+
* It can be:
|
|
9
|
+
* - A string representing a CSS selector (e.g., `#elementId`)
|
|
10
|
+
* - A DOM Node or Element.
|
|
11
|
+
* - `null` (in which case, no action will be performed).
|
|
12
|
+
* @param {string | string[]} classes - A string or an array of CSS class names to add. This can be:
|
|
13
|
+
* - A space/comma-separated string of class names (e.g., `'class1 class2'`)
|
|
14
|
+
* - An array of class names (e.g., `['class1', 'class2']`)
|
|
15
|
+
* @param {Function} [intercept] - An optional callback function that intercepts the class addition process.
|
|
16
|
+
* It takes the class name as a parameter and can return:
|
|
17
|
+
* - `true`: to add the class name as it is.
|
|
18
|
+
* - A new class name (string): to replace the class name with a new one.
|
|
19
|
+
* - `false` or `undefined`: to skip adding the class.
|
|
20
|
+
* @returns {void} This function does not return a value. It modifies the target DOM element.
|
|
21
|
+
*/
|
|
22
|
+
import getEl from "./getEl";
|
|
23
|
+
import parseClasses from "./parseClasses";
|
|
24
|
+
const addClasses = (target, classes, intercept) => {
|
|
25
|
+
const el = getEl(target), arr = parseClasses(classes);
|
|
26
|
+
if (!el || arr.length === 0) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
arr.forEach((k) => {
|
|
30
|
+
let tmp;
|
|
31
|
+
if (intercept) {
|
|
32
|
+
tmp = intercept(k);
|
|
33
|
+
tmp === true ? el.classList.add(k) :
|
|
34
|
+
(typeof tmp === 'string' && tmp) ? el.classList.add(tmp) : null;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
el.classList.add(k);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
export default addClasses;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/01/07 12:04:57
|
|
3
|
+
* @namespace addClasses
|
|
4
|
+
* @description Adds one or more CSS classes to a DOM element. This function can add a list of class names
|
|
5
|
+
* either passed as a space/comma-separated string or an array of strings.
|
|
6
|
+
* It also supports an optional `intercept` callback to modify or intercept the class addition.
|
|
7
|
+
* @param {string | Node | null} target - The target DOM element, Node, or CSS selector to which the classes will be added.
|
|
8
|
+
* It can be:
|
|
9
|
+
* - A string representing a CSS selector (e.g., `#elementId`)
|
|
10
|
+
* - A DOM Node or Element.
|
|
11
|
+
* - `null` (in which case, no action will be performed).
|
|
12
|
+
* @param {string | string[]} classes - A string or an array of CSS class names to add. This can be:
|
|
13
|
+
* - A space/comma-separated string of class names (e.g., `'class1 class2'`)
|
|
14
|
+
* - An array of class names (e.g., `['class1', 'class2']`)
|
|
15
|
+
* @param {Function} [intercept] - An optional callback function that intercepts the class addition process.
|
|
16
|
+
* It takes the class name as a parameter and can return:
|
|
17
|
+
* - `true`: to add the class name as it is.
|
|
18
|
+
* - A new class name (string): to replace the class name with a new one.
|
|
19
|
+
* - `false` or `undefined`: to skip adding the class.
|
|
20
|
+
* @returns {void} This function does not return a value. It modifies the target DOM element.
|
|
21
|
+
*/
|
|
22
|
+
import getEl from "./getEl";
|
|
23
|
+
import parseClasses from "./parseClasses";
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
const addClasses = (target: string | Node | null, classes: string | string[], intercept?: (className: string) => string | boolean | void): void => {
|
|
27
|
+
const el = getEl(target),
|
|
28
|
+
arr = parseClasses(classes);
|
|
29
|
+
if (!el || arr.length === 0) { return; }
|
|
30
|
+
|
|
31
|
+
arr.forEach((k: string) => {
|
|
32
|
+
let tmp: any;
|
|
33
|
+
if (intercept) {
|
|
34
|
+
tmp = intercept(k);
|
|
35
|
+
tmp === true ? (el as Element).classList.add(k) :
|
|
36
|
+
(typeof tmp === 'string' && tmp) ? (el as Element).classList.add(tmp) : null;
|
|
37
|
+
} else {
|
|
38
|
+
(el as Element).classList.add(k);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export default addClasses;
|
package/src/alias.js
ADDED
package/src/alias.ts
ADDED
package/src/classes.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/01/07 11:46:20
|
|
3
|
+
* @namespace classes
|
|
4
|
+
* @description A utility module for batch manipulation of CSS classes on DOM elements.
|
|
5
|
+
*/
|
|
6
|
+
'use strict';
|
|
7
|
+
import parseClasses from './parseClasses';
|
|
8
|
+
import getEl from './getEl';
|
|
9
|
+
import isEmpty from './isEmpty';
|
|
10
|
+
/**
|
|
11
|
+
* @description Creates an object with methods for manipulating CSS classes on a DOM element
|
|
12
|
+
* @param {string | Node} target - The target DOM element or selector (can be a CSS selector or an actual DOM element)
|
|
13
|
+
* @returns {T_classes} An object containing methods for class manipulation
|
|
14
|
+
*/
|
|
15
|
+
const classes = (target) => {
|
|
16
|
+
let el = getEl(target);
|
|
17
|
+
return {
|
|
18
|
+
/**
|
|
19
|
+
* @memberOf classes
|
|
20
|
+
* @description Retrieves an array of CSS classes currently applied to the element
|
|
21
|
+
* @returns {string[]} Array of class names
|
|
22
|
+
* @example
|
|
23
|
+
* ax.classes('#demo').get();
|
|
24
|
+
*/
|
|
25
|
+
get: () => el ? parseClasses(el.getAttribute('class') || '') : [],
|
|
26
|
+
/**
|
|
27
|
+
* @memberOf classes
|
|
28
|
+
* @description Adds one or more CSS classes to the element
|
|
29
|
+
* @param {string | string[]} classes - Class names to add (space/comma separated string or array)
|
|
30
|
+
* @param {Function} [intercept] - Optional callback to intercept class addition
|
|
31
|
+
* @returns {T_classes} The classes instance for chaining
|
|
32
|
+
* @example
|
|
33
|
+
* ax.classes('#demo').add('demo01,demo02');
|
|
34
|
+
*/
|
|
35
|
+
add: function (classes, intercept) {
|
|
36
|
+
let arr = parseClasses(classes);
|
|
37
|
+
if (!el || arr.length === 0) {
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
arr.forEach((k) => {
|
|
41
|
+
let tmp;
|
|
42
|
+
if (intercept) {
|
|
43
|
+
tmp = intercept(k);
|
|
44
|
+
tmp === true ? el.classList.add(k) :
|
|
45
|
+
(typeof tmp === 'string' && tmp) ? el.classList.add(tmp) : null;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
el.classList.add(k);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return this;
|
|
52
|
+
},
|
|
53
|
+
/**
|
|
54
|
+
* @memberOf classes
|
|
55
|
+
* @description Removes one or more CSS classes from the element
|
|
56
|
+
* @param {string | string[]} classes - Class names to remove (space/comma separated string or array)
|
|
57
|
+
* @param {Function} [intercept] - Optional callback to intercept class removal
|
|
58
|
+
* @returns {T_classes} The classes instance for chaining
|
|
59
|
+
* @example
|
|
60
|
+
* ax.classes('#demo').remove('demo01,demo02');
|
|
61
|
+
*/
|
|
62
|
+
remove: function (classes, intercept) {
|
|
63
|
+
let arr = parseClasses(classes);
|
|
64
|
+
if (!el || arr.length === 0)
|
|
65
|
+
return this;
|
|
66
|
+
arr.forEach((k) => {
|
|
67
|
+
let tmp;
|
|
68
|
+
if (intercept) {
|
|
69
|
+
tmp = intercept(k);
|
|
70
|
+
tmp === true ? el.classList.remove(k) :
|
|
71
|
+
(typeof tmp === 'string' && tmp) ? el.classList.remove(tmp) : null;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
el.classList.remove(k);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return this;
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* @memberOf classes
|
|
81
|
+
* @description Replaces an existing CSS class with a new one
|
|
82
|
+
* @param {string} oldClass - The class name to be replaced
|
|
83
|
+
* @param {string} newClass - The new class name to apply
|
|
84
|
+
* @returns {T_classes} The classes instance for chaining
|
|
85
|
+
*/
|
|
86
|
+
replace: function (oldClass, newClass) {
|
|
87
|
+
if (!el || !oldClass)
|
|
88
|
+
return this;
|
|
89
|
+
if (el && newClass && oldClass) {
|
|
90
|
+
el.classList.remove(oldClass);
|
|
91
|
+
el.classList.add(newClass);
|
|
92
|
+
}
|
|
93
|
+
return this;
|
|
94
|
+
},
|
|
95
|
+
/**
|
|
96
|
+
* @memberOf classes
|
|
97
|
+
* @description Checks if the element has all the specified CSS classes
|
|
98
|
+
* @param {string | string[]} classes - Class names to check (space/comma separated string or array)
|
|
99
|
+
* @returns {boolean} True if the element has all specified classes, false otherwise
|
|
100
|
+
*/
|
|
101
|
+
has: function (classes) {
|
|
102
|
+
if (!el || isEmpty(classes))
|
|
103
|
+
return false;
|
|
104
|
+
let arr = parseClasses(classes);
|
|
105
|
+
for (let k of arr) {
|
|
106
|
+
if (!el.classList.contains(k)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
export default classes;
|
package/src/classes.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/01/07 11:46:20
|
|
3
|
+
* @namespace classes
|
|
4
|
+
* @description A utility module for batch manipulation of CSS classes on DOM elements.
|
|
5
|
+
*/
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
import parseClasses from './parseClasses';
|
|
9
|
+
import getEl from './getEl';
|
|
10
|
+
import isEmpty from './isEmpty';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {Function} T_fn
|
|
14
|
+
* @description Type for a function that can be used for intercepting class operations
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {Object} T_classes
|
|
19
|
+
* @description Interface for class manipulation methods
|
|
20
|
+
* @property {T_fn} get - Method to retrieve current classes of the element
|
|
21
|
+
* @property {T_fn} add - Method to add classes to the element
|
|
22
|
+
* @property {T_fn} remove - Method to remove classes from the element
|
|
23
|
+
* @property {T_fn} replace - Method to replace an old class with a new one
|
|
24
|
+
* @property {T_fn} [has] - Method to check if element has specified classes
|
|
25
|
+
*/
|
|
26
|
+
type T_classes = {
|
|
27
|
+
get: () => string[],
|
|
28
|
+
add: (classes: string | string[], intercept?: (className: string) => string | boolean | void) => T_classes,
|
|
29
|
+
remove: (classes: string | string[], intercept?: (className: string) => string | boolean | void) => T_classes,
|
|
30
|
+
replace: (oldClass: string, newClass: string) => T_classes,
|
|
31
|
+
has: (classes: string | string[]) => boolean,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @description Creates an object with methods for manipulating CSS classes on a DOM element
|
|
36
|
+
* @param {string | Node} target - The target DOM element or selector (can be a CSS selector or an actual DOM element)
|
|
37
|
+
* @returns {T_classes} An object containing methods for class manipulation
|
|
38
|
+
*/
|
|
39
|
+
const classes = (target: string | Node): T_classes => {
|
|
40
|
+
let el = getEl(target);
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
/**
|
|
44
|
+
* @memberOf classes
|
|
45
|
+
* @description Retrieves an array of CSS classes currently applied to the element
|
|
46
|
+
* @returns {string[]} Array of class names
|
|
47
|
+
* @example
|
|
48
|
+
* ax.classes('#demo').get();
|
|
49
|
+
*/
|
|
50
|
+
get: (): string[] => el ? parseClasses((el as Element).getAttribute('class') || '') : [],
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @memberOf classes
|
|
54
|
+
* @description Adds one or more CSS classes to the element
|
|
55
|
+
* @param {string | string[]} classes - Class names to add (space/comma separated string or array)
|
|
56
|
+
* @param {Function} [intercept] - Optional callback to intercept class addition
|
|
57
|
+
* @returns {T_classes} The classes instance for chaining
|
|
58
|
+
* @example
|
|
59
|
+
* ax.classes('#demo').add('demo01,demo02');
|
|
60
|
+
*/
|
|
61
|
+
add: function (classes: string | string[], intercept?: (className: string) => string | boolean | void): T_classes {
|
|
62
|
+
let arr = parseClasses(classes);
|
|
63
|
+
if (!el || arr.length === 0) { return this; }
|
|
64
|
+
|
|
65
|
+
arr.forEach((k: string) => {
|
|
66
|
+
let tmp: any;
|
|
67
|
+
if (intercept) {
|
|
68
|
+
tmp = intercept(k);
|
|
69
|
+
tmp === true ? (el as Element).classList.add(k) :
|
|
70
|
+
(typeof tmp === 'string' && tmp) ? (el as Element).classList.add(tmp) : null;
|
|
71
|
+
} else {
|
|
72
|
+
(el as Element).classList.add(k);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return this;
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @memberOf classes
|
|
80
|
+
* @description Removes one or more CSS classes from the element
|
|
81
|
+
* @param {string | string[]} classes - Class names to remove (space/comma separated string or array)
|
|
82
|
+
* @param {Function} [intercept] - Optional callback to intercept class removal
|
|
83
|
+
* @returns {T_classes} The classes instance for chaining
|
|
84
|
+
* @example
|
|
85
|
+
* ax.classes('#demo').remove('demo01,demo02');
|
|
86
|
+
*/
|
|
87
|
+
remove: function (classes: string | string[], intercept?: (className: string) => string | boolean | void): T_classes {
|
|
88
|
+
let arr = parseClasses(classes);
|
|
89
|
+
if (!el || arr.length === 0) return this;
|
|
90
|
+
|
|
91
|
+
arr.forEach((k: string) => {
|
|
92
|
+
let tmp: any;
|
|
93
|
+
if (intercept) {
|
|
94
|
+
tmp = intercept(k);
|
|
95
|
+
tmp === true ? (el as Element).classList.remove(k) :
|
|
96
|
+
(typeof tmp === 'string' && tmp) ? (el as Element).classList.remove(tmp) : null;
|
|
97
|
+
} else {
|
|
98
|
+
(el as Element).classList.remove(k);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
return this;
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @memberOf classes
|
|
106
|
+
* @description Replaces an existing CSS class with a new one
|
|
107
|
+
* @param {string} oldClass - The class name to be replaced
|
|
108
|
+
* @param {string} newClass - The new class name to apply
|
|
109
|
+
* @returns {T_classes} The classes instance for chaining
|
|
110
|
+
*/
|
|
111
|
+
replace: function (oldClass: string, newClass: string): T_classes {
|
|
112
|
+
if (!el || !oldClass) return this;
|
|
113
|
+
if (el && newClass && oldClass) {
|
|
114
|
+
(el as Element).classList.remove(oldClass);
|
|
115
|
+
(el as Element).classList.add(newClass);
|
|
116
|
+
}
|
|
117
|
+
return this;
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @memberOf classes
|
|
122
|
+
* @description Checks if the element has all the specified CSS classes
|
|
123
|
+
* @param {string | string[]} classes - Class names to check (space/comma separated string or array)
|
|
124
|
+
* @returns {boolean} True if the element has all specified classes, false otherwise
|
|
125
|
+
*/
|
|
126
|
+
has: function (classes: string | string[]): boolean {
|
|
127
|
+
if (!el || isEmpty(classes)) return false;
|
|
128
|
+
|
|
129
|
+
let arr = parseClasses(classes);
|
|
130
|
+
for (let k of arr) {
|
|
131
|
+
if (!(el as Element).classList.contains(k)) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export default classes;
|
package/src/comma.js
ADDED
package/src/comma.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/01/07 13:37:57
|
|
3
|
+
* @function createTools
|
|
4
|
+
* @description Creates a group of icon button tools and appends them to a parent element.
|
|
5
|
+
* The `data` array can contain tool definitions, where each tool can be defined either as an object or a string shorthand.
|
|
6
|
+
* @param {toolsItem[]} data - The data representing the tools. Each item in the array can be an object with properties for the tool or a string representing a shorthand tool.
|
|
7
|
+
* @param {Element | string} parent - The DOM element or selector where the tools will be appended.
|
|
8
|
+
* @returns {HTMLElement} The container element that holds the tools.
|
|
9
|
+
* @example
|
|
10
|
+
* ax.createTools([{},{},'toggle','close']);
|
|
11
|
+
* <!-- Returns a node containing the tool buttons -->
|
|
12
|
+
*/
|
|
13
|
+
'use strict';
|
|
14
|
+
import createEl from './createEl';
|
|
15
|
+
import isEmpty from './isEmpty';
|
|
16
|
+
import ALIAS from './alias';
|
|
17
|
+
import NAMESPACE from './namespace';
|
|
18
|
+
import addClasses from './addClasses';
|
|
19
|
+
/**
|
|
20
|
+
* @description Creates a set of icon button tools and appends them to the specified parent element.
|
|
21
|
+
* @param {toolsItem[]} data - The tool data, each tool can be either an object or a shorthand string.
|
|
22
|
+
* @returns {HTMLElement} The container DOM element that holds the tools.
|
|
23
|
+
*/
|
|
24
|
+
const createTools = (data) => {
|
|
25
|
+
/*! data = [
|
|
26
|
+
{
|
|
27
|
+
name: 'close',
|
|
28
|
+
nodeName: 'span',
|
|
29
|
+
icon:'',
|
|
30
|
+
disk:'',
|
|
31
|
+
cube:'',
|
|
32
|
+
image:'',
|
|
33
|
+
attrs: {},
|
|
34
|
+
classes:'',
|
|
35
|
+
styles:'',
|
|
36
|
+
label:'',
|
|
37
|
+
expandable:false,
|
|
38
|
+
focusable:true,
|
|
39
|
+
action: null,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'max',
|
|
43
|
+
nodeName: 'span',
|
|
44
|
+
icon:'',
|
|
45
|
+
attrs: {},
|
|
46
|
+
classes:'',
|
|
47
|
+
styles:'',
|
|
48
|
+
label:'',
|
|
49
|
+
expandable:false,
|
|
50
|
+
action: null,
|
|
51
|
+
},
|
|
52
|
+
] */
|
|
53
|
+
const toolsEl = createEl('span', { class: `${NAMESPACE}-box-tools` }), renderFn = (props) => {
|
|
54
|
+
const dftAttrs = {}, arrow = props.extendable ? `<i ${ALIAS}="arrow"></i>` : '', iconStr = props.icon ? `<i ${ALIAS}="icon">${props.icon}</i>` : '', diskStr = props.disk ? `<i ${ALIAS}="disk"><img src="${props.disk}"/></i>` : '', cubeStr = props.cube ? `<i ${ALIAS}="cube"><img src="${props.cube}"/></i>` : '', imageStr = props.image ? `<i ${ALIAS}="image"><img src="${props.image}"/></i>` : '', label = props.label ? `<i ${ALIAS}="label">${props.label}</i>` : '', html = iconStr + diskStr + cubeStr + imageStr + label + arrow;
|
|
55
|
+
//使用title提示
|
|
56
|
+
props.title && (dftAttrs.title = props.title);
|
|
57
|
+
//可聚焦,增加tabindex=1
|
|
58
|
+
props.focusable && (dftAttrs.tabindex = 1);
|
|
59
|
+
//attrs是其他属性,可能会覆盖title、tabindex
|
|
60
|
+
props.wrapEl = createEl(props.nodeName || 'span', Object.assign(dftAttrs, props.attrs), html);
|
|
61
|
+
props.iconEl = props.wrapEl.querySelector(`[${ALIAS}="icon"]`);
|
|
62
|
+
props.cubeEl = props.wrapEl.querySelector(`[${ALIAS}="cube"]`);
|
|
63
|
+
props.diskEl = props.wrapEl.querySelector(`[${ALIAS}="disk"]`);
|
|
64
|
+
props.imageEl = props.wrapEl.querySelector(`[${ALIAS}="image"]`);
|
|
65
|
+
props.labelEl = props.wrapEl.querySelector(`[${ALIAS}="label"]`);
|
|
66
|
+
//增加classes和styles
|
|
67
|
+
!isEmpty(props.classes) && addClasses(props.wrapEl, props.classes);
|
|
68
|
+
!isEmpty(props.styles) && (props.wrapEl.style.cssText += props.styles);
|
|
69
|
+
};
|
|
70
|
+
//此处不用map方法,是避免改变原data的内存地址指向
|
|
71
|
+
for (let item of data) {
|
|
72
|
+
//data=[{},{},'toggle','close']
|
|
73
|
+
renderFn(item);
|
|
74
|
+
toolsEl.appendChild(item.wrapEl);
|
|
75
|
+
item?.action?.(item);
|
|
76
|
+
}
|
|
77
|
+
return toolsEl;
|
|
78
|
+
};
|
|
79
|
+
export default createTools;
|