ziya-utils 1.1.5 → 1.1.6

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.
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).ZiyaUtils={})}(this,function(t){"use strict";function e(t,e,n,o){return new(n||(n=Promise))(function(i,s){function r(t){try{c(o.next(t))}catch(t){s(t)}}function a(t){try{c(o.throw(t))}catch(t){s(t)}}function c(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n(function(t){t(e)})).then(r,a)}c((o=o.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;const n={PHONE:/^1[3-9]\d{9}$/,EMAIL:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,ID_CARD:/(^\d{15}$)|(^\d{17}(\d|X|x)$)/,URL:/^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/,IPV4:/^(\d{1,3}\.){3}\d{1,3}$/,STRONG_PASSWORD:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,CHINESE:/^[\u4e00-\u9fa5]+$/};class o{}class i extends o{static isPhone(t){return n.PHONE.test(t)}static isEmail(t){return n.EMAIL.test(t)}static isIdCard(t){return n.ID_CARD.test(t)}static isUrl(t){return n.URL.test(t)}static isIpv4(t){return n.IPV4.test(t)}static isStrongPassword(t){return n.STRONG_PASSWORD.test(t)}static isChinese(t){return n.CHINESE.test(t)}}var s={patterns:n,validator:i};const r=t=>{if(!t)return"";const e=Math.max(t.lastIndexOf("/"),t.lastIndexOf("\\"));return-1===e?t:t.slice(e+1)};function a(t){if("string"==typeof t){if(!/^\d+$/.test(t))return!1;t=Number(t)}if("number"!=typeof t||isNaN(t))return!1;const e=41024448e5;return 13===t.toString().length?t>=0&&t<=e:10===t.toString().length&&(t>=0&&t<=4102444800)}const c=t=>a(t)&&10===t.toString().length;class l{constructor(t={}){var e;this.interceptRules=[],this.isActive=!1,this.originalXMLHttpRequest=window.XMLHttpRequest,this.enableLogging=null===(e=t.enableLogging)||void 0===e||e}start(){if(this.isActive)return void this.log("拦截器已经启动");const t=this;window.XMLHttpRequest=function(){const e=new t.originalXMLHttpRequest;let n="";const o=e.open;e.open=function(t,e,i=!0,s,r){return n="string"==typeof e?e:e.toString(),o.call(this,t,e,i,s,r)};const i=e.send;return e.send=function(o){const s=t.findMatchingRule(n);if(!s)return i.call(this,o);let r=o;if(s.requestCallback&&o)try{r=s.requestCallback(o)}catch(t){console.error("XHR请求拦截器处理失败:",t),r=o}const a=e.onreadystatechange;return e.onreadystatechange=function(o){if(4===e.readyState&&e.status>=200&&e.status<300)try{const o=JSON.parse(e.responseText),i=s.responseCallback(o);Object.defineProperty(e,"responseText",{writable:!0,configurable:!0,value:JSON.stringify(i)}),Object.defineProperty(e,"response",{writable:!0,configurable:!0,value:JSON.stringify(i)}),t.log(`已拦截并修改响应: ${n}`)}catch(e){t.log("拦截器处理失败:",e)}a&&a.call(this,o)},i.call(this,r)},e},Object.setPrototypeOf(window.XMLHttpRequest,this.originalXMLHttpRequest),window.XMLHttpRequest.prototype=this.originalXMLHttpRequest.prototype,this.isActive=!0,this.log("XHR拦截器已启动")}stop(){this.isActive?(window.XMLHttpRequest=this.originalXMLHttpRequest,this.isActive=!1,this.log("XHR拦截器已停止,已恢复原始XMLHttpRequest")):this.log("拦截器未启动")}setRules(t){this.interceptRules=[...t],this.log("已设置拦截规则:",t.map(t=>t.url))}addRule(t,e,n){this.interceptRules.push({url:t,responseCallback:e,requestCallback:n}),this.log(`已添加拦截规则: ${t}`)}removeRule(t){const e=this.interceptRules.length;this.interceptRules=this.interceptRules.filter(e=>e.url!==t);const n=this.interceptRules.length<e;return n?this.log(`已移除拦截规则: ${t}`):this.log(`未找到拦截规则: ${t}`),n}clearRules(){this.interceptRules=[],this.log("已清除所有拦截规则")}getRules(){return[...this.interceptRules]}getStatus(){return{isActive:this.isActive,rulesCount:this.interceptRules.length}}findMatchingRule(t){return this.interceptRules.find(e=>t.includes(e.url))}log(t,...e){this.enableLogging&&console.log(`[XHRInterceptor] ${t}`,...e)}}const u=new l({enableLogging:!0}),d="ziya-utils";t.Lib_Name=d,t.RegexPatterns=n,t.RegexValidator=i,t.XHRInterceptor=l,t.addStyleStr=(t="")=>{let e=document.createElement("style");return e.innerHTML=t,document.getElementsByTagName("head")[0].appendChild(e),e},t.copyToClipboard=function(t){return e(this,void 0,void 0,function*(){try{var e=JSON.stringify(t);if(navigator.clipboard&&(window.isSecureContext||"https:"===location.protocol||"localhost"===location.hostname))return yield navigator.clipboard.writeText(e),!0;var n=document.createElement("textarea");n.value=e,n.style.position="fixed",n.style.left="-9999px",n.style.top="-9999px",document.body.appendChild(n),n.select();var o=document.execCommand("copy");return document.body.removeChild(n),o}catch(t){return console.error("复制失败:",t),!1}})},t.createFormData=function(t){const e=new FormData;if("string"==typeof t){const n=new URLSearchParams(t);for(const[t,o]of n)e.append(t,o)}else"object"==typeof t&&null!==t&&Object.keys(t).forEach(n=>{const o=t[n];null!=o?Array.isArray(o)?o.forEach(t=>e.append(n,String(t))):o instanceof File||o instanceof Blob?e.append(n,o):"object"==typeof o?e.append(n,JSON.stringify(o)):e.append(n,String(o)):e.append(n,"")});return e},t.createMaskLoading=(t="加载中...",e="")=>{const n=`${d}-mask-loading-container`,o=document.getElementById(n);o&&document.body.removeChild(o);const i=document.createElement("div");i.id=n,i.innerHTML=`\n <div class="mask"></div>\n <div class="message">${t}</div>\n `;const s=document.createElement("style");return s.innerHTML=`\n #${n} {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 9999;\n transition: opacity 0.3s;\n }\n #${n} .mask {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.45);\n }\n #${n} .message {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\n }\n\n ${e}\n `,document.head.appendChild(s),document.body.append(i),{close:()=>{document.body.removeChild(i)},updateMsg:t=>{i.querySelector(".message").innerHTML=t}}},t.downloadSingleFile=(t,n)=>e(void 0,void 0,void 0,function*(){if(!t||!s.validator.isUrl(t))throw new Error("无效的URL");try{const e=yield fetch(t);if(!e.ok)throw new Error(`下载失败: ${e.status} ${e.statusText}`);let o=n;if(!o){o=r(t);const e=o.indexOf("?");-1!==e&&(o=o.substring(0,e)),o||(o="downloaded_file")}const i=yield e.blob(),s=URL.createObjectURL(i),a=document.createElement("a");a.href=s,a.download=o,document.body.appendChild(a),a.click(),setTimeout(()=>{URL.revokeObjectURL(s),a.remove()},100)}catch(t){throw console.error("文件下载失败:",t),t}}),t.extractFileNameFromPath=r,t.formatDateTypeSafe=function(t,e){return function(t,e){const n=e||new Date,o=(t,e=2)=>t.toString().padStart(e,"0"),i={year:n.getFullYear(),month:n.getMonth()+1,day:n.getDate(),hours:n.getHours(),minutes:n.getMinutes(),seconds:n.getSeconds(),milliseconds:n.getMilliseconds()},s={YYYY:i.year.toString(),YY:i.year.toString().slice(-2),MM:o(i.month),M:i.month.toString(),DD:o(i.day),D:i.day.toString(),HH:o(i.hours),H:i.hours.toString(),mm:o(i.minutes),m:i.minutes.toString(),ss:o(i.seconds),s:i.seconds.toString(),SSS:o(i.milliseconds,3)};return Object.keys(s).sort((t,e)=>e.length-t.length).reduce((t,e)=>t.replace(new RegExp(e,"g"),s[e]),t)}(t,e)},t.getElapsedTimeSince=t=>{const e=Date.now();a(t)||(t=e);const n=Math.max(0,e-(c(t)?1e3*t:t));return{hours:Math.floor(n/36e5),minutes:Math.floor(n%36e5/6e4),seconds:Math.floor(n%6e4/1e3)}},t.getUuid=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){var e=16*Math.random()|0;return("x"==t?e:3&e|8).toString(16)})},t.isMillisecondTimestamp=t=>a(t)&&13===t.toString().length,t.isSecondTimestamp=c,t.isValidTimestamp=a,t.precisionFormat=function(t,e,n=!0,o=!0){var i=t<0&&o?-1:1;const s=Math.pow(10,e);return n?Math.round(t*s*i)/s*i:Math.floor(t*s*i)/s*i},t.sleep=t=>new Promise(e=>{setTimeout(()=>{e(!0)},1e3*t)}),t.xhrInterceptor=u});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ZiyaUtils={})}(this,function(e){"use strict";function t(e,t,n,o){return new(n||(n=Promise))(function(s,r){function i(e){try{c(o.next(e))}catch(e){r(e)}}function a(e){try{c(o.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?s(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(i,a)}c((o=o.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;const n={PHONE:/^1[3-9]\d{9}$/,EMAIL:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,ID_CARD:/(^\d{15}$)|(^\d{17}(\d|X|x)$)/,URL:/^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/,IPV4:/^(\d{1,3}\.){3}\d{1,3}$/,STRONG_PASSWORD:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,CHINESE:/^[\u4e00-\u9fa5]+$/};class o{}class s extends o{static isPhone(e){return n.PHONE.test(e)}static isEmail(e){return n.EMAIL.test(e)}static isIdCard(e){return n.ID_CARD.test(e)}static isUrl(e){return n.URL.test(e)}static isIpv4(e){return n.IPV4.test(e)}static isStrongPassword(e){return n.STRONG_PASSWORD.test(e)}static isChinese(e){return n.CHINESE.test(e)}}var r={patterns:n,validator:s};const i=e=>{if(!e)return"";const t=Math.max(e.lastIndexOf("/"),e.lastIndexOf("\\"));return-1===t?e:e.slice(t+1)};function a(e){if("string"==typeof e){if(!/^\d+$/.test(e))return!1;e=Number(e)}if("number"!=typeof e||isNaN(e))return!1;const t=41024448e5;return 13===e.toString().length?e>=0&&e<=t:10===e.toString().length&&(e>=0&&e<=4102444800)}const c=e=>a(e)&&10===e.toString().length;class l{constructor(e={}){var t;this.interceptRules=[],this.isActive=!1,this.originalXMLHttpRequest=window.XMLHttpRequest,this.enableLogging=null===(t=e.enableLogging)||void 0===t||t}start(){if(this.isActive)return void this.log("拦截器已经启动");const e=this;window.XMLHttpRequest=function(){const t=new e.originalXMLHttpRequest;let n="";const o=t.open;t.open=function(e,t,s=!0,r,i){return n="string"==typeof t?t:t.toString(),o.call(this,e,t,s,r,i)};const s=t.send;return t.send=function(o){const r=e.findMatchingRule(n);if(!r)return s.call(this,o);let i=o;if(r.requestCallback&&o)try{i=r.requestCallback(o)}catch(e){console.error("XHR请求拦截器处理失败:",e),i=o}const a=t.onreadystatechange;return t.onreadystatechange=function(o){if(4===t.readyState&&t.status>=200&&t.status<300)try{const o=JSON.parse(t.responseText),s=r.responseCallback(o);Object.defineProperty(t,"responseText",{writable:!0,configurable:!0,value:JSON.stringify(s)}),Object.defineProperty(t,"response",{writable:!0,configurable:!0,value:JSON.stringify(s)}),e.log(`已拦截并修改响应: ${n}`)}catch(t){e.log("拦截器处理失败:",t)}a&&a.call(this,o)},s.call(this,i)},t},Object.setPrototypeOf(window.XMLHttpRequest,this.originalXMLHttpRequest),window.XMLHttpRequest.prototype=this.originalXMLHttpRequest.prototype,this.isActive=!0,this.log("XHR拦截器已启动")}stop(){this.isActive?(window.XMLHttpRequest=this.originalXMLHttpRequest,this.isActive=!1,this.log("XHR拦截器已停止,已恢复原始XMLHttpRequest")):this.log("拦截器未启动")}setRules(e){this.interceptRules=[...e],this.log("已设置拦截规则:",e.map(e=>e.url))}addRule(e,t,n){this.interceptRules.push({url:e,responseCallback:t,requestCallback:n}),this.log(`已添加拦截规则: ${e}`)}removeRule(e){const t=this.interceptRules.length;this.interceptRules=this.interceptRules.filter(t=>t.url!==e);const n=this.interceptRules.length<t;return n?this.log(`已移除拦截规则: ${e}`):this.log(`未找到拦截规则: ${e}`),n}clearRules(){this.interceptRules=[],this.log("已清除所有拦截规则")}getRules(){return[...this.interceptRules]}getStatus(){return{isActive:this.isActive,rulesCount:this.interceptRules.length}}findMatchingRule(e){return this.interceptRules.find(t=>e.includes(t.url))}log(e,...t){this.enableLogging&&console.log(`[XHRInterceptor] ${e}`,...t)}}const u=new l({enableLogging:!0}),d="ziya-utils";e.Lib_Name=d,e.RegexPatterns=n,e.RegexValidator=s,e.ScriptDomBuilder=class{constructor(e=document.body,t="glk-script-container"){this.container=null,this.elements=new Map,this.data=new Map,this.styleElement=null,this.parentNode=e,this.containerId=t}createMain(e,t="",n={}){return t&&this.createStyles(t),this.container=this.createElement("div",Object.assign({id:this.containerId},n)),e.forEach((e,t)=>{const n=this.createItem(e,t);n&&this.container.appendChild(n)}),this.parentNode.appendChild(this.container),{container:this.container,get:e=>this.getChild(e),getValue:e=>this.getValue(e),setValue:(e,t)=>this.setValue(e,t),show:e=>this.show(e),hide:e=>this.hide(e),remove:()=>this.remove(),on:(e,t,n)=>this.on(e,t,n),getData:e=>this.getData(e),setData:(e,t)=>this.setData(e,t)}}createStyles(e){this.styleElement=document.createElement("style"),this.styleElement.textContent=e,document.head.appendChild(this.styleElement)}createItem(e,t){const{type:n,keyword:o}=e;!function(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var s=0;for(o=Object.getOwnPropertySymbols(e);s<o.length;s++)t.indexOf(o[s])<0&&Object.prototype.propertyIsEnumerable.call(e,o[s])&&(n[o[s]]=e[o[s]])}}(e,["type","keyword"]);let s=null;switch(n){case"input":s=this.createInput(e);break;case"button":s=this.createButton(e);break;case"select":s=this.createSelect(e);break;case"textarea":s=this.createTextarea(e);break;case"checkbox":s=this.createCheckbox(e);break;case"label":s=this.createLabel(e);break;case"div":s=this.createDiv(e);break;default:return console.warn(`未支持的元素类型: ${n}`),null}return o&&s&&(this.setChild(o,s),e.saveToLocal&&this.isFormElement(n)&&this.handleLocalStorage(s,e,n)),s}isFormElement(e){return["input","textarea","select","checkbox"].includes(e)}handleLocalStorage(e,t,n){const o=this.getStorageKey(t.keyword),s=this.getFromLocalStorage(o);if(null!==s)if("checkbox"===n){const t=e.querySelector('input[type="checkbox"]');t&&(t.checked="true"===s)}else{e.value=s}else if("checkbox"===n){const n=e.querySelector('input[type="checkbox"]');n&&(n.checked=t.checked||!1)}else{e.value=t.value||""}if("checkbox"===n){const t=e.querySelector('input[type="checkbox"]');t&&t.addEventListener("change",e=>{const t=e.target;this.saveToLocalStorage(o,t.checked.toString())})}else{const t="select"===n?"change":"input";e.addEventListener(t,e=>{const t=e.target;this.saveToLocalStorage(o,t.value)})}}createInput(e){const t=this.createElement("input",Object.assign({type:e.inputType||"text",name:e.keyword,placeholder:e.placeholder||"",value:e.value||""},e.props));return this.bindEvents(t,e),t}createButton(e){const t=this.createElement("button",Object.assign({textContent:e.text||e.keyword||"Button",name:e.keyword},e.props));return this.bindEvents(t,e),t}createSelect(e){const t=this.createElement("select",Object.assign({name:e.keyword},e.props));return e.options&&e.options.forEach(e=>{const n=document.createElement("option");"string"==typeof e?(n.value=e,n.textContent=e):(n.value=e.value||e.text||"",n.textContent=e.text||e.value||"",e.selected&&(n.selected=!0)),t.appendChild(n)}),this.bindEvents(t,e),t}createTextarea(e){const t=this.createElement("textarea",Object.assign({name:e.keyword,placeholder:e.placeholder||"",value:e.value||"",rows:e.rows||3},e.props));return this.bindEvents(t,e),t}createCheckbox(e){const t=document.createElement("div"),n=this.createElement("input",Object.assign({type:"checkbox",id:e.keyword,name:e.keyword,checked:e.checked||!1},e.props)),o=document.createElement("label");return o.setAttribute("for",e.keyword||""),o.textContent=e.text||e.keyword||"Checkbox",this.bindEvents(n,e),t.appendChild(n),t.appendChild(o),e.keyword&&this.setChild(e.keyword,n),t}createLabel(e){return this.createElement("label",Object.assign({textContent:e.text||e.keyword||"",name:e.keyword},e.props))}createDiv(e){const t=this.createElement("div",Object.assign({textContent:e.text||"",innerHTML:e.html||void 0,name:e.keyword},e.props));return this.bindEvents(t,e),t}createElement(e,t={}){const n=document.createElement(e);return Object.keys(t).forEach(e=>{"innerHTML"===e?n.innerHTML=t[e]:n[e]=t[e]}),n}bindEvents(e,t){["onClick","onChange","onInput","onFocus","onBlur","onMouseEnter","onMouseLeave"].forEach(n=>{const o=t[n];if(o){const t=n.slice(2).toLowerCase();e.addEventListener(t,o)}})}getChild(e){return this.elements.get(e)||null}setChild(e,t){this.elements.has(e)||this.elements.set(e,t)}getValue(e){const t=this.getChild(e);if(!t)return null;if("checkbox"===t.type)return t.checked;return t.value||t.textContent||null}setValue(e,t){const n=this.getChild(e);if(n)if("checkbox"===n.type)n.checked=Boolean(t);else{const e=n;void 0!==e.value?e.value=String(t):n.textContent=String(t)}}show(e){if(e){const t=this.getChild(e);if(t){const e="checkbox"===t.type?t.parentElement:t;e&&(e.style.display="")}}else this.container&&(this.container.style.display="")}hide(e){if(e){const t=this.getChild(e);if(t){const e="checkbox"===t.type?t.parentElement:t;e&&(e.style.display="none")}}else this.container&&(this.container.style.display="none")}remove(){this.container&&(this.container.remove(),this.container=null,this.elements.clear()),this.styleElement&&(this.styleElement.remove(),this.styleElement=null)}on(e,t,n){const o=this.getChild(e);o&&o.addEventListener(t,n)}getStorageKey(e){return`${this.containerId}_${e}`}saveToLocalStorage(e,t){try{localStorage.setItem(e,t)}catch(e){console.warn("无法保存到本地存储:",e)}}getFromLocalStorage(e){try{return localStorage.getItem(e)}catch(e){return console.warn("无法从本地存储读取:",e),null}}setData(e,t){this.data.set(e,t)}getData(e){return this.data.get(e)}},e.XHRInterceptor=l,e.addStyleStr=(e="")=>{let t=document.createElement("style");return t.innerHTML=e,document.getElementsByTagName("head")[0].appendChild(t),t},e.copyToClipboard=function(e){return t(this,void 0,void 0,function*(){try{var t=JSON.stringify(e);if(navigator.clipboard&&(window.isSecureContext||"https:"===location.protocol||"localhost"===location.hostname))return yield navigator.clipboard.writeText(t),!0;var n=document.createElement("textarea");n.value=t,n.style.position="fixed",n.style.left="-9999px",n.style.top="-9999px",document.body.appendChild(n),n.select();var o=document.execCommand("copy");return document.body.removeChild(n),o}catch(e){return console.error("复制失败:",e),!1}})},e.createAsyncTask=function(e=()=>null,n=()=>{},o={}){const{duration:s=1,timeout:r,immediate:i=!1}=o;return new Promise((o,a)=>{let c=null,l=null;const u=()=>{c&&(clearInterval(c),c=null),l&&(clearTimeout(l),l=null)},d=()=>t(this,void 0,void 0,function*(){try{const t=yield e();if(t){u();const e=yield n(t);o(e)}}catch(e){u(),a(e)}});r&&r>0&&(l=setTimeout(()=>{u(),a(new Error(`${r} 秒后任务将会超时。`))},1e3*r)),i&&d(),c=setInterval(d,1e3*s)})},e.createFormData=function(e){const t=new FormData;if("string"==typeof e){const n=new URLSearchParams(e);for(const[e,o]of n)t.append(e,o)}else"object"==typeof e&&null!==e&&Object.keys(e).forEach(n=>{const o=e[n];null!=o?Array.isArray(o)?o.forEach(e=>t.append(n,String(e))):o instanceof File||o instanceof Blob?t.append(n,o):"object"==typeof o?t.append(n,JSON.stringify(o)):t.append(n,String(o)):t.append(n,"")});return t},e.createMaskLoading=(e="加载中...",t="")=>{const n=`${d}-mask-loading-container`,o=document.getElementById(n);o&&document.body.removeChild(o);const s=document.createElement("div");s.id=n,s.innerHTML=`\n <div class="mask"></div>\n <div class="message">${e}</div>\n `;const r=document.createElement("style");return r.innerHTML=`\n #${n} {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 9999;\n transition: opacity 0.3s;\n }\n #${n} .mask {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.45);\n }\n #${n} .message {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\n }\n\n ${t}\n `,document.head.appendChild(r),document.body.append(s),{close:()=>{document.body.removeChild(s)},updateMsg:e=>{s.querySelector(".message").innerHTML=e}}},e.downloadSingleFile=(e,n)=>t(void 0,void 0,void 0,function*(){if(!e||!r.validator.isUrl(e))throw new Error("无效的URL");try{const t=yield fetch(e);if(!t.ok)throw new Error(`下载失败: ${t.status} ${t.statusText}`);let o=n;if(!o){o=i(e);const t=o.indexOf("?");-1!==t&&(o=o.substring(0,t)),o||(o="downloaded_file")}const s=yield t.blob(),r=URL.createObjectURL(s),a=document.createElement("a");a.href=r,a.download=o,document.body.appendChild(a),a.click(),setTimeout(()=>{URL.revokeObjectURL(r),a.remove()},100)}catch(e){throw console.error("文件下载失败:",e),e}}),e.extractFileNameFromPath=i,e.formatDateTypeSafe=function(e,t){return function(e,t){const n=t||new Date,o=(e,t=2)=>e.toString().padStart(t,"0"),s={year:n.getFullYear(),month:n.getMonth()+1,day:n.getDate(),hours:n.getHours(),minutes:n.getMinutes(),seconds:n.getSeconds(),milliseconds:n.getMilliseconds()},r={YYYY:s.year.toString(),YY:s.year.toString().slice(-2),MM:o(s.month),M:s.month.toString(),DD:o(s.day),D:s.day.toString(),HH:o(s.hours),H:s.hours.toString(),mm:o(s.minutes),m:s.minutes.toString(),ss:o(s.seconds),s:s.seconds.toString(),SSS:o(s.milliseconds,3)};return Object.keys(r).sort((e,t)=>t.length-e.length).reduce((e,t)=>e.replace(new RegExp(t,"g"),r[t]),e)}(e,t)},e.getElapsedTimeSince=e=>{const t=Date.now();a(e)||(e=t);const n=Math.max(0,t-(c(e)?1e3*e:e));return{hours:Math.floor(n/36e5),minutes:Math.floor(n%36e5/6e4),seconds:Math.floor(n%6e4/1e3)}},e.getUuid=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})},e.isMillisecondTimestamp=e=>a(e)&&13===e.toString().length,e.isSecondTimestamp=c,e.isValidTimestamp=a,e.precisionFormat=function(e,t,n=!0,o=!0){var s=e<0&&o?-1:1;const r=Math.pow(10,t);return n?Math.round(e*r*s)/r*s:Math.floor(e*r*s)/r*s},e.sleep=e=>new Promise(t=>{setTimeout(()=>{t(!0)},1e3*e)}),e.xhrInterceptor=u});
@@ -0,0 +1,57 @@
1
+ import { __awaiter } from '../node_modules/tslib/tslib.es6.js';
2
+
3
+ /**
4
+ * 创建异步任务,定时检查条件直到满足后执行初始化函数
5
+ * @param checkFun 检查函数,返回 true 值时表示条件满足
6
+ * @param initFun 初始化函数,在条件满足后执行
7
+ * @param options 配置选项
8
+ * @returns Promise,resolve 初始化函数的返回值
9
+ */
10
+ function createAsyncTask(checkFun = () => null, initFun = () => undefined, options = {}) {
11
+ const { duration = 1, timeout, immediate = false } = options;
12
+ return new Promise((resolve, reject) => {
13
+ let timer = null;
14
+ let timeoutTimer = null;
15
+ // 清理定时器
16
+ const cleanup = () => {
17
+ if (timer) {
18
+ clearInterval(timer);
19
+ timer = null;
20
+ }
21
+ if (timeoutTimer) {
22
+ clearTimeout(timeoutTimer);
23
+ timeoutTimer = null;
24
+ }
25
+ };
26
+ // 检查逻辑
27
+ const check = () => __awaiter(this, void 0, void 0, function* () {
28
+ try {
29
+ const res = yield checkFun();
30
+ if (res) {
31
+ cleanup();
32
+ const res2 = yield initFun(res);
33
+ resolve(res2);
34
+ }
35
+ }
36
+ catch (error) {
37
+ cleanup();
38
+ reject(error);
39
+ }
40
+ });
41
+ // 设置超时
42
+ if (timeout && timeout > 0) {
43
+ timeoutTimer = setTimeout(() => {
44
+ cleanup();
45
+ reject(new Error(`${timeout} 秒后任务将会超时。`));
46
+ }, timeout * 1000);
47
+ }
48
+ // 立即执行一次检查
49
+ if (immediate) {
50
+ check();
51
+ }
52
+ // 设置定时检查
53
+ timer = setInterval(check, duration * 1000);
54
+ });
55
+ }
56
+
57
+ export { createAsyncTask };
@@ -3,6 +3,11 @@
3
3
  * @created 2025-04-02
4
4
  * @author glk
5
5
  */
6
+ /**
7
+ * 向head追加一个样式表
8
+ * @param styStr
9
+ * @returns
10
+ */
6
11
  declare const addStyleStr: (styStr?: string) => HTMLStyleElement;
7
12
  /**
8
13
  * 创建一个全局唯一的遮罩 Loading
@@ -22,3 +27,4 @@ declare const createMaskLoading: (msg?: string, style?: string) => {
22
27
  updateMsg: (msg: string) => void;
23
28
  };
24
29
  export { addStyleStr, createMaskLoading };
30
+ export * from "./script-dom-builder";
@@ -1,10 +1,16 @@
1
1
  import { Lib_Name } from '../constant/index.js';
2
+ import '../node_modules/tslib/tslib.es6.js';
2
3
 
3
4
  /**
4
5
  * @fileoverview Document 模块
5
6
  * @created 2025-04-02
6
7
  * @author glk
7
8
  */
9
+ /**
10
+ * 向head追加一个样式表
11
+ * @param styStr
12
+ * @returns
13
+ */
8
14
  const addStyleStr = (styStr = "") => {
9
15
  let _style = document.createElement("style");
10
16
  _style.innerHTML = styStr;
@@ -0,0 +1,80 @@
1
+ interface ElementConfig {
2
+ type: 'input' | 'button' | 'select' | 'textarea' | 'checkbox' | 'label' | 'div';
3
+ keyword?: string;
4
+ saveToLocal?: boolean;
5
+ inputType?: string;
6
+ placeholder?: string;
7
+ value?: string;
8
+ text?: string;
9
+ options?: Array<{
10
+ value?: string;
11
+ text?: string;
12
+ selected?: boolean;
13
+ } | string>;
14
+ rows?: number;
15
+ checked?: boolean;
16
+ html?: string;
17
+ props?: Record<string, any>;
18
+ onClick?: (event: Event) => void;
19
+ onChange?: (event: Event) => void;
20
+ onInput?: (event: Event) => void;
21
+ onFocus?: (event: Event) => void;
22
+ onBlur?: (event: Event) => void;
23
+ onMouseEnter?: (event: Event) => void;
24
+ onMouseLeave?: (event: Event) => void;
25
+ }
26
+ interface ContainerConfig {
27
+ [key: string]: any;
28
+ }
29
+ interface DOMBuilderReturn {
30
+ container: HTMLDivElement;
31
+ get: (keyword: string) => HTMLElement | null;
32
+ getValue: (keyword: string) => string | boolean | null;
33
+ setValue: (keyword: string, value: string | boolean) => void;
34
+ show: (keyword?: string) => void;
35
+ hide: (keyword?: string) => void;
36
+ remove: () => void;
37
+ on: (keyword: string, event: string, handler: (event: Event) => void) => void;
38
+ getData: (key: string) => any;
39
+ setData: (key: string, value: any) => void;
40
+ }
41
+ /**
42
+ * 开发浏览器脚本DOM构建器
43
+ */
44
+ declare class ScriptDomBuilder {
45
+ private parentNode;
46
+ private container;
47
+ private elements;
48
+ private data;
49
+ private containerId;
50
+ private styleElement;
51
+ constructor(parentNode?: HTMLElement, containerId?: string);
52
+ createMain(items: ElementConfig[], styles?: string, containerConfig?: ContainerConfig): DOMBuilderReturn;
53
+ private createStyles;
54
+ private createItem;
55
+ private isFormElement;
56
+ private handleLocalStorage;
57
+ private createInput;
58
+ private createButton;
59
+ private createSelect;
60
+ private createTextarea;
61
+ private createCheckbox;
62
+ private createLabel;
63
+ private createDiv;
64
+ private createElement;
65
+ private bindEvents;
66
+ private getChild;
67
+ private setChild;
68
+ private getValue;
69
+ private setValue;
70
+ private show;
71
+ private hide;
72
+ private remove;
73
+ private on;
74
+ private getStorageKey;
75
+ private saveToLocalStorage;
76
+ private getFromLocalStorage;
77
+ private setData;
78
+ private getData;
79
+ }
80
+ export { ScriptDomBuilder };
@@ -0,0 +1,366 @@
1
+ import { __rest } from '../node_modules/tslib/tslib.es6.js';
2
+
3
+ /**
4
+ * 开发浏览器脚本DOM构建器
5
+ */
6
+ class ScriptDomBuilder {
7
+ constructor(parentNode = document.body, containerId = "glk-script-container") {
8
+ this.container = null;
9
+ this.elements = new Map();
10
+ this.data = new Map();
11
+ this.styleElement = null;
12
+ this.parentNode = parentNode;
13
+ this.containerId = containerId;
14
+ }
15
+ // 创建主容器和子元素
16
+ createMain(items, styles = "", containerConfig = {}) {
17
+ // 创建样式
18
+ if (styles) {
19
+ this.createStyles(styles);
20
+ }
21
+ // 创建容器
22
+ this.container = this.createElement("div", Object.assign({ id: this.containerId }, containerConfig));
23
+ // 创建子元素
24
+ items.forEach((item, index) => {
25
+ const element = this.createItem(item, index);
26
+ if (element) {
27
+ this.container.appendChild(element);
28
+ }
29
+ });
30
+ // 添加到父节点
31
+ this.parentNode.appendChild(this.container);
32
+ return {
33
+ container: this.container,
34
+ get: (keyword) => this.getChild(keyword),
35
+ getValue: (keyword) => this.getValue(keyword),
36
+ setValue: (keyword, value) => this.setValue(keyword, value),
37
+ show: (keyword) => this.show(keyword),
38
+ hide: (keyword) => this.hide(keyword),
39
+ remove: () => this.remove(),
40
+ on: (keyword, event, handler) => this.on(keyword, event, handler),
41
+ getData: (key) => this.getData(key),
42
+ setData: (key, value) => this.setData(key, value),
43
+ };
44
+ }
45
+ // 创建样式
46
+ createStyles(styles) {
47
+ this.styleElement = document.createElement("style");
48
+ this.styleElement.textContent = styles;
49
+ document.head.appendChild(this.styleElement);
50
+ }
51
+ // 创建单个元素
52
+ createItem(config, index) {
53
+ const { type, keyword } = config; __rest(config, ["type", "keyword"]);
54
+ let element = null;
55
+ switch (type) {
56
+ case "input":
57
+ element = this.createInput(config);
58
+ break;
59
+ case "button":
60
+ element = this.createButton(config);
61
+ break;
62
+ case "select":
63
+ element = this.createSelect(config);
64
+ break;
65
+ case "textarea":
66
+ element = this.createTextarea(config);
67
+ break;
68
+ case "checkbox":
69
+ element = this.createCheckbox(config);
70
+ break;
71
+ case "label":
72
+ element = this.createLabel(config);
73
+ break;
74
+ case "div":
75
+ element = this.createDiv(config);
76
+ break;
77
+ default:
78
+ console.warn(`未支持的元素类型: ${type}`);
79
+ return null;
80
+ }
81
+ // 存储元素引用
82
+ if (keyword && element) {
83
+ this.setChild(keyword, element);
84
+ // 处理本地存储逻辑
85
+ if (config.saveToLocal && this.isFormElement(type)) {
86
+ this.handleLocalStorage(element, config, type);
87
+ }
88
+ }
89
+ return element;
90
+ }
91
+ // 判断是否为表单元素
92
+ isFormElement(type) {
93
+ return ["input", "textarea", "select", "checkbox"].includes(type);
94
+ }
95
+ // 处理本地存储逻辑
96
+ handleLocalStorage(element, config, type) {
97
+ const storageKey = this.getStorageKey(config.keyword);
98
+ const savedValue = this.getFromLocalStorage(storageKey);
99
+ // 设置初始值
100
+ if (savedValue !== null) {
101
+ // 有本地存储值,使用本地值
102
+ if (type === "checkbox") {
103
+ const checkbox = element.querySelector('input[type="checkbox"]');
104
+ if (checkbox) {
105
+ checkbox.checked = savedValue === "true";
106
+ }
107
+ }
108
+ else {
109
+ const formElement = element;
110
+ formElement.value = savedValue;
111
+ }
112
+ }
113
+ else {
114
+ // 没有本地存储值,使用初始值或空值
115
+ if (type === "checkbox") {
116
+ const checkbox = element.querySelector('input[type="checkbox"]');
117
+ if (checkbox) {
118
+ checkbox.checked = config.checked || false;
119
+ }
120
+ }
121
+ else {
122
+ const formElement = element;
123
+ formElement.value = config.value || "";
124
+ }
125
+ }
126
+ // 绑定实时保存事件
127
+ if (type === "checkbox") {
128
+ const checkbox = element.querySelector('input[type="checkbox"]');
129
+ if (checkbox) {
130
+ checkbox.addEventListener("change", (e) => {
131
+ const target = e.target;
132
+ this.saveToLocalStorage(storageKey, target.checked.toString());
133
+ });
134
+ }
135
+ }
136
+ else {
137
+ const eventType = type === "select" ? "change" : "input";
138
+ element.addEventListener(eventType, (e) => {
139
+ const target = e.target;
140
+ this.saveToLocalStorage(storageKey, target.value);
141
+ });
142
+ }
143
+ }
144
+ // 创建输入框
145
+ createInput(config) {
146
+ const input = this.createElement("input", Object.assign({ type: config.inputType || "text", name: config.keyword, placeholder: config.placeholder || "", value: config.value || "" }, config.props));
147
+ // 绑定事件
148
+ this.bindEvents(input, config);
149
+ return input;
150
+ }
151
+ // 创建按钮
152
+ createButton(config) {
153
+ const button = this.createElement("button", Object.assign({ textContent: config.text || config.keyword || "Button", name: config.keyword }, config.props));
154
+ // 绑定事件
155
+ this.bindEvents(button, config);
156
+ return button;
157
+ }
158
+ // 创建下拉框
159
+ createSelect(config) {
160
+ const select = this.createElement("select", Object.assign({ name: config.keyword }, config.props));
161
+ // 添加选项
162
+ if (config.options) {
163
+ config.options.forEach((option) => {
164
+ const optionEl = document.createElement("option");
165
+ if (typeof option === 'string') {
166
+ optionEl.value = option;
167
+ optionEl.textContent = option;
168
+ }
169
+ else {
170
+ optionEl.value = option.value || option.text || '';
171
+ optionEl.textContent = option.text || option.value || '';
172
+ if (option.selected)
173
+ optionEl.selected = true;
174
+ }
175
+ select.appendChild(optionEl);
176
+ });
177
+ }
178
+ // 绑定事件
179
+ this.bindEvents(select, config);
180
+ return select;
181
+ }
182
+ // 创建文本域
183
+ createTextarea(config) {
184
+ const textarea = this.createElement("textarea", Object.assign({ name: config.keyword, placeholder: config.placeholder || "", value: config.value || "", rows: config.rows || 3 }, config.props));
185
+ // 绑定事件
186
+ this.bindEvents(textarea, config);
187
+ return textarea;
188
+ }
189
+ // 创建复选框
190
+ createCheckbox(config) {
191
+ const wrapper = document.createElement("div");
192
+ const checkbox = this.createElement("input", Object.assign({ type: "checkbox", id: config.keyword, name: config.keyword, checked: config.checked || false }, config.props));
193
+ const label = document.createElement("label");
194
+ label.setAttribute("for", config.keyword || '');
195
+ label.textContent = config.text || config.keyword || "Checkbox";
196
+ // 绑定事件
197
+ this.bindEvents(checkbox, config);
198
+ wrapper.appendChild(checkbox);
199
+ wrapper.appendChild(label);
200
+ // 将checkbox存储为主要元素
201
+ if (config.keyword) {
202
+ this.setChild(config.keyword, checkbox);
203
+ }
204
+ return wrapper;
205
+ }
206
+ // 创建标签
207
+ createLabel(config) {
208
+ return this.createElement("label", Object.assign({ textContent: config.text || config.keyword || "", name: config.keyword }, config.props));
209
+ }
210
+ // 创建DIV
211
+ createDiv(config) {
212
+ const div = this.createElement("div", Object.assign({ textContent: config.text || "", innerHTML: config.html || undefined, name: config.keyword }, config.props));
213
+ // 绑定事件
214
+ this.bindEvents(div, config);
215
+ return div;
216
+ }
217
+ // 通用元素创建方法
218
+ createElement(tag, props = {}) {
219
+ const element = document.createElement(tag);
220
+ Object.keys(props).forEach((key) => {
221
+ if (key === "innerHTML") {
222
+ element.innerHTML = props[key];
223
+ }
224
+ else {
225
+ element[key] = props[key];
226
+ }
227
+ });
228
+ return element;
229
+ }
230
+ // 绑定事件
231
+ bindEvents(element, config) {
232
+ const eventTypes = ["onClick", "onChange", "onInput", "onFocus", "onBlur", "onMouseEnter", "onMouseLeave"];
233
+ eventTypes.forEach((eventType) => {
234
+ const handler = config[eventType];
235
+ if (handler) {
236
+ const eventName = eventType.slice(2).toLowerCase();
237
+ element.addEventListener(eventName, handler);
238
+ }
239
+ });
240
+ }
241
+ // 获取子元素
242
+ getChild(keyword) {
243
+ return this.elements.get(keyword) || null;
244
+ }
245
+ // 设置子元素
246
+ setChild(keyword, element) {
247
+ if (!this.elements.has(keyword)) {
248
+ this.elements.set(keyword, element);
249
+ }
250
+ }
251
+ // 获取元素值
252
+ getValue(keyword) {
253
+ const element = this.getChild(keyword);
254
+ if (!element)
255
+ return null;
256
+ if (element.type === "checkbox") {
257
+ return element.checked;
258
+ }
259
+ const formElement = element;
260
+ return formElement.value || element.textContent || null;
261
+ }
262
+ // 设置元素值
263
+ setValue(keyword, value) {
264
+ const element = this.getChild(keyword);
265
+ if (!element)
266
+ return;
267
+ if (element.type === "checkbox") {
268
+ element.checked = Boolean(value);
269
+ }
270
+ else {
271
+ const formElement = element;
272
+ if (formElement.value !== undefined) {
273
+ formElement.value = String(value);
274
+ }
275
+ else {
276
+ element.textContent = String(value);
277
+ }
278
+ }
279
+ }
280
+ // 显示容器或子元素
281
+ show(keyword) {
282
+ if (keyword) {
283
+ const element = this.getChild(keyword);
284
+ if (element) {
285
+ // 显示元素,如果是checkbox,显示其父容器
286
+ const targetElement = element.type === "checkbox" ? element.parentElement : element;
287
+ if (targetElement) {
288
+ targetElement.style.display = "";
289
+ }
290
+ }
291
+ }
292
+ else {
293
+ if (this.container) {
294
+ this.container.style.display = "";
295
+ }
296
+ }
297
+ }
298
+ // 隐藏容器或子元素
299
+ hide(keyword) {
300
+ if (keyword) {
301
+ const element = this.getChild(keyword);
302
+ if (element) {
303
+ // 隐藏元素,如果是checkbox,隐藏其父容器
304
+ const targetElement = element.type === "checkbox" ? element.parentElement : element;
305
+ if (targetElement) {
306
+ targetElement.style.display = "none";
307
+ }
308
+ }
309
+ }
310
+ else {
311
+ if (this.container) {
312
+ this.container.style.display = "none";
313
+ }
314
+ }
315
+ }
316
+ // 移除容器
317
+ remove() {
318
+ if (this.container) {
319
+ this.container.remove();
320
+ this.container = null;
321
+ this.elements.clear();
322
+ }
323
+ if (this.styleElement) {
324
+ this.styleElement.remove();
325
+ this.styleElement = null;
326
+ }
327
+ }
328
+ // 事件绑定
329
+ on(keyword, event, handler) {
330
+ const element = this.getChild(keyword);
331
+ if (element) {
332
+ element.addEventListener(event, handler);
333
+ }
334
+ }
335
+ // 获取存储key
336
+ getStorageKey(keyword) {
337
+ return `${this.containerId}_${keyword}`;
338
+ }
339
+ // 本地存储相关方法
340
+ saveToLocalStorage(key, value) {
341
+ try {
342
+ localStorage.setItem(key, value);
343
+ }
344
+ catch (e) {
345
+ console.warn("无法保存到本地存储:", e);
346
+ }
347
+ }
348
+ getFromLocalStorage(key) {
349
+ try {
350
+ return localStorage.getItem(key);
351
+ }
352
+ catch (e) {
353
+ console.warn("无法从本地存储读取:", e);
354
+ return null;
355
+ }
356
+ }
357
+ // 内存数据存储
358
+ setData(key, value) {
359
+ this.data.set(key, value);
360
+ }
361
+ getData(key) {
362
+ return this.data.get(key);
363
+ }
364
+ }
365
+
366
+ export { ScriptDomBuilder };
package/es/index.d.ts CHANGED
@@ -8,3 +8,4 @@ export * from "./count";
8
8
  export * from "./xhr";
9
9
  export * from "./constant";
10
10
  export * from "./document";
11
+ export * from "./async";
package/es/index.js CHANGED
@@ -8,3 +8,5 @@ export { precisionFormat } from './count/index.js';
8
8
  export { XHRInterceptor, xhrInterceptor } from './xhr/index.js';
9
9
  export { Lib_Name } from './constant/index.js';
10
10
  export { addStyleStr, createMaskLoading } from './document/index.js';
11
+ export { createAsyncTask } from './async/index.js';
12
+ export { ScriptDomBuilder } from './document/script-dom-builder.js';
@@ -15,6 +15,18 @@ PERFORMANCE OF THIS SOFTWARE.
15
15
  /* global Reflect, Promise, SuppressedError, Symbol */
16
16
 
17
17
 
18
+ function __rest(s, e) {
19
+ var t = {};
20
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
21
+ t[p] = s[p];
22
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
23
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
24
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
25
+ t[p[i]] = s[p[i]];
26
+ }
27
+ return t;
28
+ }
29
+
18
30
  function __awaiter(thisArg, _arguments, P, generator) {
19
31
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
20
32
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -30,4 +42,4 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
30
42
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
31
43
  };
32
44
 
33
- export { __awaiter };
45
+ export { __awaiter, __rest };
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ var tslib_es6 = require('../node_modules/tslib/tslib.es6.js');
4
+
5
+ /**
6
+ * 创建异步任务,定时检查条件直到满足后执行初始化函数
7
+ * @param checkFun 检查函数,返回 true 值时表示条件满足
8
+ * @param initFun 初始化函数,在条件满足后执行
9
+ * @param options 配置选项
10
+ * @returns Promise,resolve 初始化函数的返回值
11
+ */
12
+ function createAsyncTask(checkFun = () => null, initFun = () => undefined, options = {}) {
13
+ const { duration = 1, timeout, immediate = false } = options;
14
+ return new Promise((resolve, reject) => {
15
+ let timer = null;
16
+ let timeoutTimer = null;
17
+ // 清理定时器
18
+ const cleanup = () => {
19
+ if (timer) {
20
+ clearInterval(timer);
21
+ timer = null;
22
+ }
23
+ if (timeoutTimer) {
24
+ clearTimeout(timeoutTimer);
25
+ timeoutTimer = null;
26
+ }
27
+ };
28
+ // 检查逻辑
29
+ const check = () => tslib_es6.__awaiter(this, void 0, void 0, function* () {
30
+ try {
31
+ const res = yield checkFun();
32
+ if (res) {
33
+ cleanup();
34
+ const res2 = yield initFun(res);
35
+ resolve(res2);
36
+ }
37
+ }
38
+ catch (error) {
39
+ cleanup();
40
+ reject(error);
41
+ }
42
+ });
43
+ // 设置超时
44
+ if (timeout && timeout > 0) {
45
+ timeoutTimer = setTimeout(() => {
46
+ cleanup();
47
+ reject(new Error(`${timeout} 秒后任务将会超时。`));
48
+ }, timeout * 1000);
49
+ }
50
+ // 立即执行一次检查
51
+ if (immediate) {
52
+ check();
53
+ }
54
+ // 设置定时检查
55
+ timer = setInterval(check, duration * 1000);
56
+ });
57
+ }
58
+
59
+ exports.createAsyncTask = createAsyncTask;
@@ -3,6 +3,11 @@
3
3
  * @created 2025-04-02
4
4
  * @author glk
5
5
  */
6
+ /**
7
+ * 向head追加一个样式表
8
+ * @param styStr
9
+ * @returns
10
+ */
6
11
  declare const addStyleStr: (styStr?: string) => HTMLStyleElement;
7
12
  /**
8
13
  * 创建一个全局唯一的遮罩 Loading
@@ -22,3 +27,4 @@ declare const createMaskLoading: (msg?: string, style?: string) => {
22
27
  updateMsg: (msg: string) => void;
23
28
  };
24
29
  export { addStyleStr, createMaskLoading };
30
+ export * from "./script-dom-builder";
@@ -1,12 +1,18 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('../constant/index.js');
4
+ require('../node_modules/tslib/tslib.es6.js');
4
5
 
5
6
  /**
6
7
  * @fileoverview Document 模块
7
8
  * @created 2025-04-02
8
9
  * @author glk
9
10
  */
11
+ /**
12
+ * 向head追加一个样式表
13
+ * @param styStr
14
+ * @returns
15
+ */
10
16
  const addStyleStr = (styStr = "") => {
11
17
  let _style = document.createElement("style");
12
18
  _style.innerHTML = styStr;
@@ -0,0 +1,80 @@
1
+ interface ElementConfig {
2
+ type: 'input' | 'button' | 'select' | 'textarea' | 'checkbox' | 'label' | 'div';
3
+ keyword?: string;
4
+ saveToLocal?: boolean;
5
+ inputType?: string;
6
+ placeholder?: string;
7
+ value?: string;
8
+ text?: string;
9
+ options?: Array<{
10
+ value?: string;
11
+ text?: string;
12
+ selected?: boolean;
13
+ } | string>;
14
+ rows?: number;
15
+ checked?: boolean;
16
+ html?: string;
17
+ props?: Record<string, any>;
18
+ onClick?: (event: Event) => void;
19
+ onChange?: (event: Event) => void;
20
+ onInput?: (event: Event) => void;
21
+ onFocus?: (event: Event) => void;
22
+ onBlur?: (event: Event) => void;
23
+ onMouseEnter?: (event: Event) => void;
24
+ onMouseLeave?: (event: Event) => void;
25
+ }
26
+ interface ContainerConfig {
27
+ [key: string]: any;
28
+ }
29
+ interface DOMBuilderReturn {
30
+ container: HTMLDivElement;
31
+ get: (keyword: string) => HTMLElement | null;
32
+ getValue: (keyword: string) => string | boolean | null;
33
+ setValue: (keyword: string, value: string | boolean) => void;
34
+ show: (keyword?: string) => void;
35
+ hide: (keyword?: string) => void;
36
+ remove: () => void;
37
+ on: (keyword: string, event: string, handler: (event: Event) => void) => void;
38
+ getData: (key: string) => any;
39
+ setData: (key: string, value: any) => void;
40
+ }
41
+ /**
42
+ * 开发浏览器脚本DOM构建器
43
+ */
44
+ declare class ScriptDomBuilder {
45
+ private parentNode;
46
+ private container;
47
+ private elements;
48
+ private data;
49
+ private containerId;
50
+ private styleElement;
51
+ constructor(parentNode?: HTMLElement, containerId?: string);
52
+ createMain(items: ElementConfig[], styles?: string, containerConfig?: ContainerConfig): DOMBuilderReturn;
53
+ private createStyles;
54
+ private createItem;
55
+ private isFormElement;
56
+ private handleLocalStorage;
57
+ private createInput;
58
+ private createButton;
59
+ private createSelect;
60
+ private createTextarea;
61
+ private createCheckbox;
62
+ private createLabel;
63
+ private createDiv;
64
+ private createElement;
65
+ private bindEvents;
66
+ private getChild;
67
+ private setChild;
68
+ private getValue;
69
+ private setValue;
70
+ private show;
71
+ private hide;
72
+ private remove;
73
+ private on;
74
+ private getStorageKey;
75
+ private saveToLocalStorage;
76
+ private getFromLocalStorage;
77
+ private setData;
78
+ private getData;
79
+ }
80
+ export { ScriptDomBuilder };
@@ -0,0 +1,368 @@
1
+ 'use strict';
2
+
3
+ var tslib_es6 = require('../node_modules/tslib/tslib.es6.js');
4
+
5
+ /**
6
+ * 开发浏览器脚本DOM构建器
7
+ */
8
+ class ScriptDomBuilder {
9
+ constructor(parentNode = document.body, containerId = "glk-script-container") {
10
+ this.container = null;
11
+ this.elements = new Map();
12
+ this.data = new Map();
13
+ this.styleElement = null;
14
+ this.parentNode = parentNode;
15
+ this.containerId = containerId;
16
+ }
17
+ // 创建主容器和子元素
18
+ createMain(items, styles = "", containerConfig = {}) {
19
+ // 创建样式
20
+ if (styles) {
21
+ this.createStyles(styles);
22
+ }
23
+ // 创建容器
24
+ this.container = this.createElement("div", Object.assign({ id: this.containerId }, containerConfig));
25
+ // 创建子元素
26
+ items.forEach((item, index) => {
27
+ const element = this.createItem(item, index);
28
+ if (element) {
29
+ this.container.appendChild(element);
30
+ }
31
+ });
32
+ // 添加到父节点
33
+ this.parentNode.appendChild(this.container);
34
+ return {
35
+ container: this.container,
36
+ get: (keyword) => this.getChild(keyword),
37
+ getValue: (keyword) => this.getValue(keyword),
38
+ setValue: (keyword, value) => this.setValue(keyword, value),
39
+ show: (keyword) => this.show(keyword),
40
+ hide: (keyword) => this.hide(keyword),
41
+ remove: () => this.remove(),
42
+ on: (keyword, event, handler) => this.on(keyword, event, handler),
43
+ getData: (key) => this.getData(key),
44
+ setData: (key, value) => this.setData(key, value),
45
+ };
46
+ }
47
+ // 创建样式
48
+ createStyles(styles) {
49
+ this.styleElement = document.createElement("style");
50
+ this.styleElement.textContent = styles;
51
+ document.head.appendChild(this.styleElement);
52
+ }
53
+ // 创建单个元素
54
+ createItem(config, index) {
55
+ const { type, keyword } = config; tslib_es6.__rest(config, ["type", "keyword"]);
56
+ let element = null;
57
+ switch (type) {
58
+ case "input":
59
+ element = this.createInput(config);
60
+ break;
61
+ case "button":
62
+ element = this.createButton(config);
63
+ break;
64
+ case "select":
65
+ element = this.createSelect(config);
66
+ break;
67
+ case "textarea":
68
+ element = this.createTextarea(config);
69
+ break;
70
+ case "checkbox":
71
+ element = this.createCheckbox(config);
72
+ break;
73
+ case "label":
74
+ element = this.createLabel(config);
75
+ break;
76
+ case "div":
77
+ element = this.createDiv(config);
78
+ break;
79
+ default:
80
+ console.warn(`未支持的元素类型: ${type}`);
81
+ return null;
82
+ }
83
+ // 存储元素引用
84
+ if (keyword && element) {
85
+ this.setChild(keyword, element);
86
+ // 处理本地存储逻辑
87
+ if (config.saveToLocal && this.isFormElement(type)) {
88
+ this.handleLocalStorage(element, config, type);
89
+ }
90
+ }
91
+ return element;
92
+ }
93
+ // 判断是否为表单元素
94
+ isFormElement(type) {
95
+ return ["input", "textarea", "select", "checkbox"].includes(type);
96
+ }
97
+ // 处理本地存储逻辑
98
+ handleLocalStorage(element, config, type) {
99
+ const storageKey = this.getStorageKey(config.keyword);
100
+ const savedValue = this.getFromLocalStorage(storageKey);
101
+ // 设置初始值
102
+ if (savedValue !== null) {
103
+ // 有本地存储值,使用本地值
104
+ if (type === "checkbox") {
105
+ const checkbox = element.querySelector('input[type="checkbox"]');
106
+ if (checkbox) {
107
+ checkbox.checked = savedValue === "true";
108
+ }
109
+ }
110
+ else {
111
+ const formElement = element;
112
+ formElement.value = savedValue;
113
+ }
114
+ }
115
+ else {
116
+ // 没有本地存储值,使用初始值或空值
117
+ if (type === "checkbox") {
118
+ const checkbox = element.querySelector('input[type="checkbox"]');
119
+ if (checkbox) {
120
+ checkbox.checked = config.checked || false;
121
+ }
122
+ }
123
+ else {
124
+ const formElement = element;
125
+ formElement.value = config.value || "";
126
+ }
127
+ }
128
+ // 绑定实时保存事件
129
+ if (type === "checkbox") {
130
+ const checkbox = element.querySelector('input[type="checkbox"]');
131
+ if (checkbox) {
132
+ checkbox.addEventListener("change", (e) => {
133
+ const target = e.target;
134
+ this.saveToLocalStorage(storageKey, target.checked.toString());
135
+ });
136
+ }
137
+ }
138
+ else {
139
+ const eventType = type === "select" ? "change" : "input";
140
+ element.addEventListener(eventType, (e) => {
141
+ const target = e.target;
142
+ this.saveToLocalStorage(storageKey, target.value);
143
+ });
144
+ }
145
+ }
146
+ // 创建输入框
147
+ createInput(config) {
148
+ const input = this.createElement("input", Object.assign({ type: config.inputType || "text", name: config.keyword, placeholder: config.placeholder || "", value: config.value || "" }, config.props));
149
+ // 绑定事件
150
+ this.bindEvents(input, config);
151
+ return input;
152
+ }
153
+ // 创建按钮
154
+ createButton(config) {
155
+ const button = this.createElement("button", Object.assign({ textContent: config.text || config.keyword || "Button", name: config.keyword }, config.props));
156
+ // 绑定事件
157
+ this.bindEvents(button, config);
158
+ return button;
159
+ }
160
+ // 创建下拉框
161
+ createSelect(config) {
162
+ const select = this.createElement("select", Object.assign({ name: config.keyword }, config.props));
163
+ // 添加选项
164
+ if (config.options) {
165
+ config.options.forEach((option) => {
166
+ const optionEl = document.createElement("option");
167
+ if (typeof option === 'string') {
168
+ optionEl.value = option;
169
+ optionEl.textContent = option;
170
+ }
171
+ else {
172
+ optionEl.value = option.value || option.text || '';
173
+ optionEl.textContent = option.text || option.value || '';
174
+ if (option.selected)
175
+ optionEl.selected = true;
176
+ }
177
+ select.appendChild(optionEl);
178
+ });
179
+ }
180
+ // 绑定事件
181
+ this.bindEvents(select, config);
182
+ return select;
183
+ }
184
+ // 创建文本域
185
+ createTextarea(config) {
186
+ const textarea = this.createElement("textarea", Object.assign({ name: config.keyword, placeholder: config.placeholder || "", value: config.value || "", rows: config.rows || 3 }, config.props));
187
+ // 绑定事件
188
+ this.bindEvents(textarea, config);
189
+ return textarea;
190
+ }
191
+ // 创建复选框
192
+ createCheckbox(config) {
193
+ const wrapper = document.createElement("div");
194
+ const checkbox = this.createElement("input", Object.assign({ type: "checkbox", id: config.keyword, name: config.keyword, checked: config.checked || false }, config.props));
195
+ const label = document.createElement("label");
196
+ label.setAttribute("for", config.keyword || '');
197
+ label.textContent = config.text || config.keyword || "Checkbox";
198
+ // 绑定事件
199
+ this.bindEvents(checkbox, config);
200
+ wrapper.appendChild(checkbox);
201
+ wrapper.appendChild(label);
202
+ // 将checkbox存储为主要元素
203
+ if (config.keyword) {
204
+ this.setChild(config.keyword, checkbox);
205
+ }
206
+ return wrapper;
207
+ }
208
+ // 创建标签
209
+ createLabel(config) {
210
+ return this.createElement("label", Object.assign({ textContent: config.text || config.keyword || "", name: config.keyword }, config.props));
211
+ }
212
+ // 创建DIV
213
+ createDiv(config) {
214
+ const div = this.createElement("div", Object.assign({ textContent: config.text || "", innerHTML: config.html || undefined, name: config.keyword }, config.props));
215
+ // 绑定事件
216
+ this.bindEvents(div, config);
217
+ return div;
218
+ }
219
+ // 通用元素创建方法
220
+ createElement(tag, props = {}) {
221
+ const element = document.createElement(tag);
222
+ Object.keys(props).forEach((key) => {
223
+ if (key === "innerHTML") {
224
+ element.innerHTML = props[key];
225
+ }
226
+ else {
227
+ element[key] = props[key];
228
+ }
229
+ });
230
+ return element;
231
+ }
232
+ // 绑定事件
233
+ bindEvents(element, config) {
234
+ const eventTypes = ["onClick", "onChange", "onInput", "onFocus", "onBlur", "onMouseEnter", "onMouseLeave"];
235
+ eventTypes.forEach((eventType) => {
236
+ const handler = config[eventType];
237
+ if (handler) {
238
+ const eventName = eventType.slice(2).toLowerCase();
239
+ element.addEventListener(eventName, handler);
240
+ }
241
+ });
242
+ }
243
+ // 获取子元素
244
+ getChild(keyword) {
245
+ return this.elements.get(keyword) || null;
246
+ }
247
+ // 设置子元素
248
+ setChild(keyword, element) {
249
+ if (!this.elements.has(keyword)) {
250
+ this.elements.set(keyword, element);
251
+ }
252
+ }
253
+ // 获取元素值
254
+ getValue(keyword) {
255
+ const element = this.getChild(keyword);
256
+ if (!element)
257
+ return null;
258
+ if (element.type === "checkbox") {
259
+ return element.checked;
260
+ }
261
+ const formElement = element;
262
+ return formElement.value || element.textContent || null;
263
+ }
264
+ // 设置元素值
265
+ setValue(keyword, value) {
266
+ const element = this.getChild(keyword);
267
+ if (!element)
268
+ return;
269
+ if (element.type === "checkbox") {
270
+ element.checked = Boolean(value);
271
+ }
272
+ else {
273
+ const formElement = element;
274
+ if (formElement.value !== undefined) {
275
+ formElement.value = String(value);
276
+ }
277
+ else {
278
+ element.textContent = String(value);
279
+ }
280
+ }
281
+ }
282
+ // 显示容器或子元素
283
+ show(keyword) {
284
+ if (keyword) {
285
+ const element = this.getChild(keyword);
286
+ if (element) {
287
+ // 显示元素,如果是checkbox,显示其父容器
288
+ const targetElement = element.type === "checkbox" ? element.parentElement : element;
289
+ if (targetElement) {
290
+ targetElement.style.display = "";
291
+ }
292
+ }
293
+ }
294
+ else {
295
+ if (this.container) {
296
+ this.container.style.display = "";
297
+ }
298
+ }
299
+ }
300
+ // 隐藏容器或子元素
301
+ hide(keyword) {
302
+ if (keyword) {
303
+ const element = this.getChild(keyword);
304
+ if (element) {
305
+ // 隐藏元素,如果是checkbox,隐藏其父容器
306
+ const targetElement = element.type === "checkbox" ? element.parentElement : element;
307
+ if (targetElement) {
308
+ targetElement.style.display = "none";
309
+ }
310
+ }
311
+ }
312
+ else {
313
+ if (this.container) {
314
+ this.container.style.display = "none";
315
+ }
316
+ }
317
+ }
318
+ // 移除容器
319
+ remove() {
320
+ if (this.container) {
321
+ this.container.remove();
322
+ this.container = null;
323
+ this.elements.clear();
324
+ }
325
+ if (this.styleElement) {
326
+ this.styleElement.remove();
327
+ this.styleElement = null;
328
+ }
329
+ }
330
+ // 事件绑定
331
+ on(keyword, event, handler) {
332
+ const element = this.getChild(keyword);
333
+ if (element) {
334
+ element.addEventListener(event, handler);
335
+ }
336
+ }
337
+ // 获取存储key
338
+ getStorageKey(keyword) {
339
+ return `${this.containerId}_${keyword}`;
340
+ }
341
+ // 本地存储相关方法
342
+ saveToLocalStorage(key, value) {
343
+ try {
344
+ localStorage.setItem(key, value);
345
+ }
346
+ catch (e) {
347
+ console.warn("无法保存到本地存储:", e);
348
+ }
349
+ }
350
+ getFromLocalStorage(key) {
351
+ try {
352
+ return localStorage.getItem(key);
353
+ }
354
+ catch (e) {
355
+ console.warn("无法从本地存储读取:", e);
356
+ return null;
357
+ }
358
+ }
359
+ // 内存数据存储
360
+ setData(key, value) {
361
+ this.data.set(key, value);
362
+ }
363
+ getData(key) {
364
+ return this.data.get(key);
365
+ }
366
+ }
367
+
368
+ exports.ScriptDomBuilder = ScriptDomBuilder;
package/lib/index.d.ts CHANGED
@@ -8,3 +8,4 @@ export * from "./count";
8
8
  export * from "./xhr";
9
9
  export * from "./constant";
10
10
  export * from "./document";
11
+ export * from "./async";
package/lib/index.js CHANGED
@@ -10,6 +10,8 @@ var index$6 = require('./count/index.js');
10
10
  var index$7 = require('./xhr/index.js');
11
11
  var index$8 = require('./constant/index.js');
12
12
  var index$9 = require('./document/index.js');
13
+ var index$a = require('./async/index.js');
14
+ var scriptDomBuilder = require('./document/script-dom-builder.js');
13
15
 
14
16
 
15
17
 
@@ -32,3 +34,5 @@ exports.xhrInterceptor = index$7.xhrInterceptor;
32
34
  exports.Lib_Name = index$8.Lib_Name;
33
35
  exports.addStyleStr = index$9.addStyleStr;
34
36
  exports.createMaskLoading = index$9.createMaskLoading;
37
+ exports.createAsyncTask = index$a.createAsyncTask;
38
+ exports.ScriptDomBuilder = scriptDomBuilder.ScriptDomBuilder;
@@ -17,6 +17,18 @@ PERFORMANCE OF THIS SOFTWARE.
17
17
  /* global Reflect, Promise, SuppressedError, Symbol */
18
18
 
19
19
 
20
+ function __rest(s, e) {
21
+ var t = {};
22
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
23
+ t[p] = s[p];
24
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
25
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
26
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
27
+ t[p[i]] = s[p[i]];
28
+ }
29
+ return t;
30
+ }
31
+
20
32
  function __awaiter(thisArg, _arguments, P, generator) {
21
33
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
22
34
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -33,3 +45,4 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
33
45
  };
34
46
 
35
47
  exports.__awaiter = __awaiter;
48
+ exports.__rest = __rest;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ziya-utils",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "A javascript tool library.",
5
5
  "main": "./lib/index.js",
6
6
  "browser": "dist/ziya-utils.js",