sync working code, and import type-doc

This commit is contained in:
lchen committed 2023-07-17 17:24:49 +08:00
1 parent 7ab7a7094a
commit 3e9ee59178
43 files changed
+1021 -1550

No files matched your search

+3
View File
@@ -23,3 +23,6 @@ dist-ssr
*.sln
*.sw?
desktop.ini
# User definition
docs
+20
View File
@@ -0,0 +1,20 @@
var AMR = (function() {
var AMR={toWAV:(function(amr){var decoded=this._decode(amr);if(!decoded){return null}var raw=new Uint8Array(decoded.buffer,decoded.byteOffset,decoded.byteLength);var out=new Uint8Array(raw.length+this.WAV_HEADER_SIZE);var offset=0;var write_int16=(function(value){var a=new Uint8Array(2);(new Int16Array(a.buffer))[0]=value;out.set(a,offset);offset+=2});var write_int32=(function(value){var a=new Uint8Array(4);(new Int32Array(a.buffer))[0]=value;out.set(a,offset);offset+=4});var write_string=(function(value){var d=(new TextEncoder("utf-8")).encode(value);out.set(d,offset);offset+=d.length});write_string("RIFF");write_int32(4+8+16+8+raw.length);write_string("WAVEfmt ");write_int32(16);var bits_per_sample=16;var sample_rate=8e3;var channels=1;var bytes_per_frame=bits_per_sample/8*channels;var bytes_per_sec=bytes_per_frame*sample_rate;write_int16(1);write_int16(1);write_int32(sample_rate);write_int32(bytes_per_sec);write_int16(bytes_per_frame);write_int16(bits_per_sample);write_string("data");write_int32(raw.length);out.set(raw,offset);return out}),decode:(function(amr){var raw=this._decode(amr);if(!raw){return null}var out=new Float32Array(raw.length);for(var i=0;i<out.length;i++){out[i]=raw[i]/32768}return out}),_decode:(function(amr){if(String.fromCharCode.apply(null,amr.subarray(0,this.AMR_HEADER.length))!==this.AMR_HEADER){return null}var decoder=this.Decoder_Interface_init();if(!decoder){return null}var out=new Int16Array(Math.floor(amr.length/6*this.PCM_BUFFER_COUNT));var buf=Module._malloc(this.AMR_BUFFER_COUNT);var decodeInBuffer=new Uint8Array(Module.HEAPU8.buffer,buf,this.AMR_BUFFER_COUNT);buf=Module._malloc(this.PCM_BUFFER_COUNT*2);var decodeOutBuffer=new Int16Array(Module.HEAPU8.buffer,buf,this.PCM_BUFFER_COUNT);var inOffset=6;var outOffset=0;while(inOffset+1<amr.length&&outOffset+1<out.length){var size=this.SIZES[amr[inOffset]>>3&15];if(inOffset+size+1>amr.length){break}decodeInBuffer.set(amr.subarray(inOffset,inOffset+size+1));this.Decoder_Interface_Decode(decoder,decodeInBuffer.byteOffset,decodeOutBuffer.byteOffset,0);if(outOffset+this.PCM_BUFFER_COUNT>out.length){var newOut=new Int16Array(out.length*2);newOut.set(out.subarray(0,outOffset));out=newOut}out.set(decodeOutBuffer,outOffset);outOffset+=this.PCM_BUFFER_COUNT;inOffset+=size+1}Module._free(decodeInBuffer.byteOffset);Module._free(decodeOutBuffer.byteOffset);this.Decoder_Interface_exit(decoder);return out.subarray(0,outOffset)}),encode:(function(pcm,pcmSampleRate,mode){if(pcmSampleRate<8e3){console.error("pcmSampleRate should not be less than 8000.");return null}if(typeof mode==="undefined"){mode=this.Mode.MR795}var encoder=this.Encoder_Interface_init();if(!encoder){return null}var buf=Module._malloc(this.PCM_BUFFER_COUNT*2);var encodeInBuffer=new Int16Array(Module.HEAPU8.buffer,buf,this.PCM_BUFFER_COUNT);buf=Module._malloc(this.AMR_BUFFER_COUNT);var encodeOutBuffer=new Uint8Array(Module.HEAPU8.buffer,buf,this.AMR_BUFFER_COUNT);var ratio=pcmSampleRate/8e3;var inLength=Math.floor(pcm.length/ratio);var inData=new Int16Array(inLength);for(var i=0;i<inLength;i++){inData[i]=pcm[Math.floor(i*ratio)]*(32768-1)}var blockSize=this.SIZES[mode]+1;var out=new Uint8Array(Math.ceil(inLength/this.PCM_BUFFER_COUNT*blockSize)+this.AMR_HEADER.length);out.set((new TextEncoder("utf-8")).encode(this.AMR_HEADER));var inOffset=0;var outOffset=this.AMR_HEADER.length;while(inOffset+this.PCM_BUFFER_COUNT<inData.length&&outOffset+blockSize<out.length){encodeInBuffer.set(inData.subarray(inOffset,inOffset+this.PCM_BUFFER_COUNT));var n=this.Encoder_Interface_Encode(encoder,mode,encodeInBuffer.byteOffset,encodeOutBuffer.byteOffset,0);if(n!=blockSize){console.error([n,blockSize]);break}out.set(encodeOutBuffer.subarray(0,n),outOffset);inOffset+=this.PCM_BUFFER_COUNT;outOffset+=n}Module._free(encodeInBuffer.byteOffset);Module._free(encodeOutBuffer.byteOffset);this.Encoder_Interface_exit(encoder);return out.subarray(0,outOffset)}),Decoder_Interface_init:(function(){console.warn("Decoder_Interface_init not initialized.");return 0}),Decoder_Interface_exit:(function(state){console.warn("Decoder_Interface_exit not initialized.")}),Decoder_Interface_Decode:(function(state,inBuffer,outBuffer,bfi){console.warn("Decoder_Interface_Decode not initialized.")}),Encoder_Interface_init:(function(dtx){console.warn("Encoder_Interface_init not initialized.");return 0}),Encoder_Interface_exit:(function(state){console.warn("Encoder_Interface_exit not initialized.")}),Encoder_Interface_Encode:(function(state,mode,speech,out,forceSpeech){console.warn("Encoder_Interface_Encode not initialized.")}),Mode:{MR475:0,MR515:1,MR59:2,MR67:3,MR74:4,MR795:5,MR102:6,MR122:7,MRDTX:8},SIZES:[12,13,15,17,19,20,26,31,5,6,5,5,0,0,0,0],AMR_BUFFER_COUNT:32,PCM_BUFFER_COUNT:160,AMR_HEADER:"#!AMR\n",WAV_HEADER_SIZE:44};var Module={canvas:{},print:(function(text){console.log(text)}),_main:(function(){AMR.Decoder_Interface_init=Module._Decoder_Interface_init;AMR.Decoder_Interface_exit=Module._Decoder_Interface_exit;AMLine truncated
var asm=(function(global,env,buffer) {
"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=0;var n=0;var o=0;var p=0;var q=global.NaN,r=global.Infinity;var s=0,t=0,u=0,v=0,w=0.0,x=0,y=0,z=0,A=0.0;var B=0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=global.Math.floor;var M=global.Math.abs;var N=global.Math.sqrt;var O=global.Math.pow;var P=global.Math.cos;var Q=global.Math.sin;var R=global.Math.tan;var S=global.Math.acos;var T=global.Math.asin;var U=global.Math.atan;var V=global.Math.atan2;var W=global.Math.exp;var X=global.Math.log;var Y=global.Math.ceil;var Z=global.Math.imul;var _=global.Math.min;var $=global.Math.clz32;var aa=env.abort;var ba=env.assert;var ca=env._sysconf;var da=env._pthread_self;var ea=env._abort;var fa=env.___setErrNo;var ga=env._sbrk;var ha=env._time;var ia=env._emscripten_set_main_loop_timing;var ja=env._emscripten_memcpy_big;var ka=env._emscripten_set_main_loop;var la=0.0;
// EMSCRIPTEN_START_FUNCS
function ma(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function na(){return i|0}function oa(a){a=a|0;i=a}function pa(a,b){a=a|0;b=b|0;i=a;j=b}function qa(a,b){a=a|0;b=b|0;if(!m){m=a;n=b}}function ra(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function sa(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function ta(a){a=a|0;B=a}function ua(){return B|0}function va(){var a=0,b=0;b=i;i=i+16|0;a=b;c[a>>2]=0;Db(a,31756)|0;i=b;return c[a>>2]|0}function wa(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Eb(d);i=b;return}function xa(a,b,c,e){a=a|0;b=b|0;c=c|0;e=e|0;Ea(a,(e|0)==0?(d[b>>0]|0)>>>3&15:15,b+1|0,c,2)|0;return}function ya(a){a=a|0;var b=0;b=Je(8)|0;Hb(b,b+4|0,a)|0;return b|0}function za(a){a=a|0;Ib(a,a+4|0);Ke(a);return}function Aa(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0;h=i;i=i+16|0;j=h;c[j>>2]=e;f=(Jb(c[b>>2]|0,c[b+4>>2]|0,e,f,g,j,3)|0)<<16>>16;a[g>>0]=d[g>>0]|0|4;i=h;return f|0}function Ba(a){a=a|0;if(!a)a=-1;else{b[a>>1]=4096;a=0}return a|0}function Ca(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;m=c[h>>2]|0;q=g<<16>>16>0;if(q){i=0;j=0;do{l=b[e+(i<<1)>>1]|0;l=Z(l,l)|0;if((l|0)!=1073741824){k=(l<<1)+j|0;if((l^j|0)>0&(k^j|0)<0){c[h>>2]=1;j=(j>>>31)+2147483647|0}else j=k}else{c[h>>2]=1;j=2147483647}i=i+1|0}while((i&65535)<<16>>16!=g<<16>>16);if((j|0)==2147483647){c[h>>2]=m;l=0;k=0;do{j=b[e+(l<<1)>>1]>>2;j=Z(j,j)|0;if((j|0)!=1073741824){i=(j<<1)+k|0;if((j^k|0)>0&(i^k|0)<0){c[h>>2]=1;k=(k>>>31)+2147483647|0}else k=i}else{c[h>>2]=1;k=2147483647}l=l+1|0}while((l&65535)<<16>>16!=g<<16>>16)}else p=8}else{j=0;p=8}if((p|0)==8)k=j>>4;if(!k){b[a>>1]=0;return}o=((pe(k)|0)&65535)+65535|0;j=o<<16>>16;if((o&65535)<<16>>16>0){i=k<<j;if((i>>j|0)==(k|0))k=i;else k=k>>31^2147483647}else{j=0-j<<16;if((j|0)<2031616)k=k>>(j>>16);else k=0}n=Ce(k,h)|0;i=c[h>>2]|0;if(q){j=0;k=0;do{m=b[d+(j<<1)>>1]|0;m=Z(m,m)|0;if((m|0)!=1073741824){l=(m<<1)+k|0;if((m^k|0)>0&(l^k|0)<0){c[h>>2]=1;k=(k>>>31)+2147483647|0}else k=l}else{c[h>>2]=1;k=2147483647}j=j+1|0}while((j&65535)<<16>>16!=g<<16>>16);if((k|0)==2147483647){c[h>>2]=i;m=0;k=0;do{l=b[d+(m<<1)>>1]>>2;l=Z(l,l)|0;if((l|0)!=1073741824){j=(l<<1)+k|0;if((l^k|0)>0&(j^k|0)<0){c[h>>2]=1;k=(k>>>31)+2147483647|0}else k=j}else{c[h>>2]=1;k=2147483647}m=m+1|0}while((m&65535)<<16>>16!=g<<16>>16)}else p=29}else{k=0;p=29}if((p|0)==29)k=k>>4;if(!k)l=0;else{j=(pe(k)|0)<<16>>16;i=o-j|0;l=i&65535;k=(Td(n,Ce(k<<j,h)|0)|0)<<16>>16;j=k<<7;i=i<<16>>16;if(l<<16>>16>0)i=l<<16>>16<31?j>>i:0;else{p=0-i<<16>>16;i=j<<p;i=(i>>p|0)==(j|0)?i:k>>24^2147483647}l=(Z(((ce(i,h)|0)<<9)+32768>>16,32767-(f&65535)<<16>>16)|0)>>>15<<16>>16}i=b[a>>1]|0;if(q){k=f<<16>>16;j=0;while(1){f=((Z(i<<16>>16,k)|0)>>>15&65535)+l|0;i=f&65535;b[e>>1]=(Z(b[e>>1]|0,f<<16>>16)|0)>>>12;j=j+1<<16>>16;if(j<<16>>16>=g<<16>>16)break;else e=e+2|0}}b[a>>1]=i;return}function Da(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;i=c[f>>2]|0;g=e<<16>>16>0;if(g){j=0;h=0;do{l=b[d+(j<<1)>>1]|0;l=Z(l,l)|0;if((l|0)!=1073741824){k=(l<<1)+h|0;if((l^h|0)>0&(k^h|0)<0){c[f>>2]=1;h=(h>>>31)+2147483647|0}else h=k}else{c[f>>2]=1;h=2147483647}j=j+1|0}while((j&65535)<<16>>16!=e<<16>>16);if((h|0)==2147483647){c[f>>2]=i;l=0;i=0;do{k=b[d+(l<<1)>>1]>>2;k=Z(k,k)|0;if((k|0)!=1073741824){j=(k<<1)+i|0;if((k^i|0)>0&(j^i|0)<0){c[f>>2]=1;i=(i>>>31)+2147483647|0}else i=j}else{c[f>>2]=1;i=2147483647}l=l+1|0}while((l&65535)<<16>>16!=e<<16>>16)}else o=8}else{h=0;o=8}if((o|0)==8)i=h>>4;if(!i)return;n=((pe(i)|0)&65535)+65535|0;k=n<<16>>16;if((n&65535)<<16>>16>0){j=i<<k;if((j>>k|0)==(i|0))i=j;else i=i>>31^2147483647}else{k=0-k<<16;if((k|0)<2031616)i=i>>(k>>16);else i=0}m=Ce(i,f)|0;i=c[f>>2]|0;if(g){j=0;h=0;do{l=b[a+(j<<1)>>1]|0;l=Z(l,l)|0;if((l|0)!=1073741824){k=(l<<1)+h|0;if((l^h|0)>0&(k^h|0)<0){c[f>>2]=1;h=(h>>>31)+2147483647|0}else h=k}else{c[f>>2]=1;h=2147483647}j=j+1|0}while((j&65535)<<16>>16!=e<<16>>16);if((h|0)==2147483647){c[f>>2]=i;i=0;j=0;do{l=b[a+(i<<1)>>1]>>2;l=Z(l,l)|0;if((l|0)!=1073741824){k=(l<<1)+j|0;if((l^j|0)>0&(k^j|0)<0){c[f>>2]=1;j=(j>>>31)+2147483647|0}else j=k}else{c[f>>2]=1;j=2147483647}i=i+1|0}while((i&65535)<<16>>16!=e<<16>>16)}else o=28}else{h=0;o=28}if((o|0)==28)j=h>>4;if(!j)g=0;else{l=pe(j)|0;k=l<<16>>16;if(l<<16>>16>0){i=j<<k;if((i>>k|0)==(j|0))j=i;else j=j>>31^2147483647}else{k=0-k<<16;if((k|0)<2031616)j=j>>(k>>16);else j=0}i=n-(l&65535)|0;k=i&65535;h=(Td(m,Ce(j,f)|0)|0)<<16>>16;g=h<<7;i=i<<16>>16;if(k<<16>>16>0)g=k<<16>>16<31?g>>i:0;else{n=0-i<<16>>16;a=g<<n;g=(a>>n|0)==(g|0)?a:h>>24^2147483647}g=ce(g,f)|0;if((g|0)>4194303)g=2147483647;else g=(g|0)<-4194304?-2147483648:g<<9;g=Ce(g,f)|0}h=(e&65535)+65535&65535;if(h<<16>>16<=-1)return;l=g<<16>>16;k=e+-1<<16>>16<<16>>16;while(1){i=d+(k<<1)|0;g=Z(b[i>>1]|0,l)|0;do if((g|0)!=1073741824){j=g<<1;if((j|0)<=268435455)if((j|0)<-268435456){b[i>>1]=-32768;break}else{b[i>>1]=g>>>12;Line truncated
function rc(d,f,g,h){d=d|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0;i=c[h+96>>2]|0;if(d>>>0<8){m=(c[h+100>>2]|0)+(d<<2)|0;l=c[m>>2]|0;a[g>>0]=b[f+(b[l>>1]<<1)>>1]<<4|d|b[f+(b[l+2>>1]<<1)>>1]<<5|b[f+(b[l+4>>1]<<1)>>1]<<6|b[f+(b[l+6>>1]<<1)>>1]<<7;l=i+(d<<1)|0;h=b[l>>1]|0;if((h+-7|0)>4){i=4;k=4;d=1;while(1){n=b[f+(b[(c[m>>2]|0)+(i<<1)>>1]<<1)>>1]|0;h=g+(d<<16>>16)|0;a[h>>0]=n;n=e[f+(b[(c[m>>2]|0)+((k|1)<<16>>16<<1)>>1]<<1)>>1]<<1|n&65535;a[h>>0]=n;n=e[f+(b[(c[m>>2]|0)+((k|2)<<16>>16<<1)>>1]<<1)>>1]<<2|n;a[h>>0]=n;n=e[f+(b[(c[m>>2]|0)+((k|3)<<16>>16<<1)>>1]<<1)>>1]<<3|n;a[h>>0]=n;n=e[f+(b[(c[m>>2]|0)+(k+4<<16>>16<<16>>16<<1)>>1]<<1)>>1]<<4|n;a[h>>0]=n;n=e[f+(b[(c[m>>2]|0)+(k+5<<16>>16<<16>>16<<1)>>1]<<1)>>1]<<5|n;a[h>>0]=n;n=e[f+(b[(c[m>>2]|0)+(k+6<<16>>16<<16>>16<<1)>>1]<<1)>>1]<<6|n;a[h>>0]=n;j=k+8<<16>>16;d=d+1<<16>>16;a[h>>0]=e[f+(b[(c[m>>2]|0)+(k+7<<16>>16<<16>>16<<1)>>1]<<1)>>1]<<7|n;i=j<<16>>16;h=b[l>>1]|0;if((i|0)>=(h+-7|0))break;else k=j}}else{j=4;d=1}l=h+4&7;if(!l)return;i=g+(d<<16>>16)|0;a[i>>0]=0;h=0;k=0;d=0;while(1){k=(e[f+(b[(c[m>>2]|0)+(j<<16>>16<<1)>>1]<<1)>>1]&255)<<h|k&255;a[i>>0]=k;d=d+1<<16>>16;h=d<<16>>16;if((h|0)>=(l|0))break;else j=j+1<<16>>16}return}if((d|0)==15){a[g>>0]=15;return}a[g>>0]=b[f>>1]<<4|d|b[f+2>>1]<<5|b[f+4>>1]<<6|b[f+6>>1]<<7;h=i+(d<<1)|0;d=b[h>>1]|0;i=((d&65535)<<16)+262144>>16;m=i&-8;k=(m+524281|0)>>>3&65535;if(k<<16>>16>0){i=((i&-8)+524281|0)>>>3;l=((i<<3)+524280&524280)+12|0;j=1;d=f+8|0;while(1){a[g+(j<<16>>16)>>0]=e[d+2>>1]<<1|e[d>>1]|e[d+4>>1]<<2|e[d+6>>1]<<3|e[d+8>>1]<<4|e[d+10>>1]<<5|e[d+12>>1]<<6|e[d+14>>1]<<7;if(k<<16>>16>1){k=k+-1<<16>>16;j=j+1<<16>>16;d=d+16|0}else break}d=b[h>>1]|0;j=(i<<16)+65536>>16}else{l=4;j=1}d=(0-m|4)+(d&65535)<<16;k=d>>16;if(!k)return;j=g+j|0;a[j>>0]=0;if((d|0)>0){d=0;i=0;h=0}else return;do{i=i&255|b[f+(l+d<<1)>>1]<<d;a[j>>0]=i;h=h+1<<16>>16;d=h<<16>>16}while((d|0)<(k|0));return}function sc(d,f,g,h){d=d|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;o=c[h+100>>2]|0;n=c[h+96>>2]|0;a[g>>0]=d&15;n=n+(d<<1)|0;i=b[n>>1]|0;if(d>>>0>=8){l=((i&65535)<<16)+-458752|0;if((l|0)>0){m=1;k=f;while(1){f=k+16|0;h=m+1<<16>>16;a[g+(m<<16>>16)>>0]=e[k+14>>1]|e[k+12>>1]<<1|((e[k+2>>1]<<6|e[k>>1]<<7|e[k+4>>1]<<5|e[k+6>>1]<<4)&240|e[k+8>>1]<<3|e[k+10>>1]<<2)&252;l=l+-524288&-65536;if((l|0)<=0)break;else{m=h;k=f}}i=b[n>>1]|0}else h=1;m=i&7;i=g+(h<<16>>16)|0;a[i>>0]=0;if(!m)return;else{j=0;k=0;l=0;h=f}while(1){k=k&255|b[h>>1]<<7-j;a[i>>0]=k;l=l+1<<16>>16;j=l<<16>>16;if((j|0)>=(m|0))break;else h=h+2|0}return}k=i<<16>>16;if(i<<16>>16>7){i=o+(d<<2)|0;h=0;m=0;j=1;while(1){p=e[f+(b[(c[i>>2]|0)+(h<<1)>>1]<<1)>>1]<<7;k=g+(j<<16>>16)|0;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|1)<<16>>16<<1)>>1]<<1)>>1]<<6|p;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|2)<<16>>16<<1)>>1]<<1)>>1]<<5|p;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|3)<<16>>16<<1)>>1]<<1)>>1]<<4|p;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|4)<<16>>16<<1)>>1]<<1)>>1]<<3|p&240;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|5)<<16>>16<<1)>>1]<<1)>>1]<<2|p;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|6)<<16>>16<<1)>>1]<<1)>>1]<<1|p;a[k>>0]=p;l=m+8<<16>>16;j=j+1<<16>>16;a[k>>0]=p&254|e[f+(b[(c[i>>2]|0)+((m|7)<<16>>16<<1)>>1]<<1)>>1];h=l<<16>>16;k=b[n>>1]|0;if((h|0)>=(k+-7|0))break;else m=l}}else{l=0;j=1}n=k&7;m=g+(j<<16>>16)|0;a[m>>0]=0;if(!n)return;j=o+(d<<2)|0;i=0;h=0;k=0;while(1){h=(e[f+(b[(c[j>>2]|0)+(l<<16>>16<<1)>>1]<<1)>>1]&255)<<7-i|h&255;a[m>>0]=h;k=k+1<<16>>16;i=k<<16>>16;if((i|0)>=(n|0))break;else l=l+1<<16>>16}return}function tc(d,f,g,h){d=d|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;o=c[h+100>>2]|0;n=c[h+96>>2]|0;a[g>>0]=d<<3;n=n+(d<<1)|0;i=b[n>>1]|0;if(d>>>0>=8){l=((i&65535)<<16)+-458752|0;if((l|0)>0){m=1;k=f;while(1){f=k+16|0;h=m+1<<16>>16;a[g+(m<<16>>16)>>0]=e[k+14>>1]|e[k+12>>1]<<1|((e[k+2>>1]<<6|e[k>>1]<<7|e[k+4>>1]<<5|e[k+6>>1]<<4)&240|e[k+8>>1]<<3|e[k+10>>1]<<2)&252;l=l+-524288&-65536;if((l|0)<=0)break;else{m=h;k=f}}i=b[n>>1]|0}else h=1;m=i&7;i=g+(h<<16>>16)|0;a[i>>0]=0;if(!m)return;else{j=0;k=0;l=0;h=f}while(1){k=k&255|b[h>>1]<<7-j;a[i>>0]=k;l=l+1<<16>>16;j=l<<16>>16;if((j|0)>=(m|0))break;else h=h+2|0}return}k=i<<16>>16;if(i<<16>>16>7){i=o+(d<<2)|0;h=0;m=0;j=1;while(1){p=e[f+(b[(c[i>>2]|0)+(h<<1)>>1]<<1)>>1]<<7;k=g+(j<<16>>16)|0;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|1)<<16>>16<<1)>>1]<<1)>>1]<<6|p;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|2)<<16>>16<<1)>>1]<<1)>>1]<<5|p;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|3)<<16>>16<<1)>>1]<<1)>>1]<<4|p;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|4)<<16>>16<<1)>>1]<<1)>>1]<<3|p&240;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|5)<<16>>16<<1)>>1]<<1)>>1]<<2|p;a[k>>0]=p;p=e[f+(b[(c[i>>2]|0)+((m|6)<<16>>16<<1)>>1]<<1)>>1]<<1|p;a[k>>0]=p;l=m+8<<16>>16;j=j+1<<16>>16;a[k>>0]=p&254|e[f+(b[(c[i>>2]|0)+((m|7)<<16>>16<<1)>>1]<<1)>>1];h=l<<16>>16;k=b[n>>1]|0;if((h|0)>=(k+-7|0))break;else m=l}}else{l=0;j=1}n=k&7;m=g+(j<<16>>16)|0;a[m>>0]=0;if(!n)return;j=o+(d<<2)|0;i=0;h=0;k=0;while(1){h=(e[f+(b[(c[j>>2]|0)+(l<<16>>16<<1)>>1]<<1)>>1]&255)<<7-i|h&255;a[m>>0]=h;k=k+1<<16>>16;i=k<<16>>16;if((i|0)>=(n|0))break;else l=l+1<<16>>16}retLine truncated
function te(a,c,d,f,g,h,j){a=a|0;c=c|0;d=d|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;C=i;i=i+144|0;t=C+120|0;y=C+100|0;A=C+80|0;B=C+60|0;z=C+40|0;q=C+20|0;r=C;ne(d,t,10,j);fe(t,y,j);if((c|0)==8){b[h>>1]=0;l=2147483647;s=0;while(1){n=s*10|0;d=0;m=0;do{x=(e[7980+(m+n<<1)>>1]|0)+(e[8140+(m<<1)>>1]|0)|0;b[r+(m<<1)>>1]=x;x=(e[t+(m<<1)>>1]|0)-(x&65535)|0;b[q+(m<<1)>>1]=x;x=x<<16;d=(Z(x>>15,x>>16)|0)+d|0;m=m+1|0}while((m|0)!=10);if((d|0)<(l|0)){u=B;p=q;o=u+20|0;do{b[u>>1]=b[p>>1]|0;u=u+2|0;p=p+2|0}while((u|0)<(o|0));u=A;p=r;o=u+20|0;do{b[u>>1]=b[p>>1]|0;u=u+2|0;p=p+2|0}while((u|0)<(o|0));u=a;p=7980+(n<<1)|0;o=u+20|0;do{b[u>>1]=b[p>>1]|0;u=u+2|0;p=p+2|0}while((u|0)<(o|0));b[h>>1]=s}else d=l;s=s+1|0;if((s|0)==8)break;else l=d}}else{d=0;do{x=Z(b[8160+(d<<1)>>1]|0,b[a+(d<<1)>>1]|0)|0;x=(x>>>15)+(e[8140+(d<<1)>>1]|0)|0;b[A+(d<<1)>>1]=x;b[B+(d<<1)>>1]=(e[t+(d<<1)>>1]|0)-x;d=d+1|0}while((d|0)!=10)}do if(c>>>0>=2){x=B+2|0;w=B+4|0;v=e[B>>1]|0;u=b[y>>1]<<1;t=e[x>>1]|0;q=b[y+2>>1]<<1;p=e[w>>1]|0;o=b[y+4>>1]<<1;if((c|0)==5){r=2147483647;h=0;d=0;s=17908;while(1){m=(Z(v-(e[s>>1]|0)<<16>>16,u)|0)>>16;m=Z(m,m)|0;n=(Z(t-(e[s+2>>1]|0)<<16>>16,q)|0)>>16;m=(Z(n,n)|0)+m|0;n=(Z(p-(e[s+4>>1]|0)<<16>>16,o)|0)>>16;n=m+(Z(n,n)|0)|0;m=(n|0)<(r|0);d=m?h:d;h=h+1<<16>>16;if(h<<16>>16>=512)break;else{r=m?n:r;s=s+6|0}}n=(d<<16>>16)*3|0;b[B>>1]=b[17908+(n<<1)>>1]|0;b[x>>1]=b[17908+(n+1<<1)>>1]|0;b[w>>1]=b[17908+(n+2<<1)>>1]|0;b[g>>1]=d;n=B+6|0;m=B+8|0;v=B+10|0;s=e[n>>1]|0;h=b[y+6>>1]<<1;r=e[m>>1]|0;q=b[y+8>>1]<<1;p=e[v>>1]|0;o=b[y+10>>1]<<1;k=2147483647;t=0;d=0;u=9716;while(1){l=(Z(h,s-(e[u>>1]|0)<<16>>16)|0)>>16;l=Z(l,l)|0;c=(Z(q,r-(e[u+2>>1]|0)<<16>>16)|0)>>16;l=(Z(c,c)|0)+l|0;c=(Z(o,p-(e[u+4>>1]|0)<<16>>16)|0)>>16;c=l+(Z(c,c)|0)|0;l=(c|0)<(k|0);d=l?t:d;t=t+1<<16>>16;if(t<<16>>16>=512)break;else{k=l?c:k;u=u+6|0}}k=(d<<16>>16)*3|0;b[n>>1]=b[9716+(k<<1)>>1]|0;b[m>>1]=b[9716+(k+1<<1)>>1]|0;b[v>>1]=b[9716+(k+2<<1)>>1]|0;b[g+2>>1]=d;k=B+12|0;b[g+4>>1]=ue(k,12788,y+12|0,512)|0;t=x;s=w;d=v;l=B;break}else{r=2147483647;h=0;d=0;s=8180;while(1){m=(Z(v-(e[s>>1]|0)<<16>>16,u)|0)>>16;m=Z(m,m)|0;n=(Z(t-(e[s+2>>1]|0)<<16>>16,q)|0)>>16;m=(Z(n,n)|0)+m|0;n=(Z(p-(e[s+4>>1]|0)<<16>>16,o)|0)>>16;n=m+(Z(n,n)|0)|0;m=(n|0)<(r|0);d=m?h:d;h=h+1<<16>>16;if(h<<16>>16>=256)break;else{r=m?n:r;s=s+6|0}}n=(d<<16>>16)*3|0;b[B>>1]=b[8180+(n<<1)>>1]|0;b[x>>1]=b[8180+(n+1<<1)>>1]|0;b[w>>1]=b[8180+(n+2<<1)>>1]|0;b[g>>1]=d;n=B+6|0;m=B+8|0;v=B+10|0;s=e[n>>1]|0;h=b[y+6>>1]<<1;r=e[m>>1]|0;q=b[y+8>>1]<<1;p=e[v>>1]|0;o=b[y+10>>1]<<1;k=2147483647;t=0;d=0;u=9716;while(1){l=(Z(h,s-(e[u>>1]|0)<<16>>16)|0)>>16;l=Z(l,l)|0;c=(Z(q,r-(e[u+2>>1]|0)<<16>>16)|0)>>16;l=(Z(c,c)|0)+l|0;c=(Z(o,p-(e[u+4>>1]|0)<<16>>16)|0)>>16;c=l+(Z(c,c)|0)|0;l=(c|0)<(k|0);d=l?t:d;t=t+1<<16>>16;if(t<<16>>16>=512)break;else{k=l?c:k;u=u+6|0}}k=(d<<16>>16)*3|0;b[n>>1]=b[9716+(k<<1)>>1]|0;b[m>>1]=b[9716+(k+1<<1)>>1]|0;b[v>>1]=b[9716+(k+2<<1)>>1]|0;b[g+2>>1]=d;k=B+12|0;b[g+4>>1]=ue(k,12788,y+12|0,512)|0;t=x;s=w;d=v;l=B;break}}else{w=B+2|0;x=B+4|0;n=e[B>>1]|0;m=b[y>>1]<<1;l=e[w>>1]|0;k=b[y+2>>1]<<1;c=e[x>>1]|0;o=b[y+4>>1]<<1;r=2147483647;h=0;d=0;s=8180;while(1){q=(Z(m,n-(e[s>>1]|0)<<16>>16)|0)>>16;q=Z(q,q)|0;p=(Z(k,l-(e[s+2>>1]|0)<<16>>16)|0)>>16;q=(Z(p,p)|0)+q|0;p=(Z(o,c-(e[s+4>>1]|0)<<16>>16)|0)>>16;p=q+(Z(p,p)|0)|0;q=(p|0)<(r|0);d=q?h:d;h=h+1<<16>>16;if(h<<16>>16>=256)break;else{r=q?p:r;s=s+6|0}}n=(d<<16>>16)*3|0;b[B>>1]=b[8180+(n<<1)>>1]|0;b[w>>1]=b[8180+(n+1<<1)>>1]|0;b[x>>1]=b[8180+(n+2<<1)>>1]|0;b[g>>1]=d;n=B+6|0;m=B+8|0;v=B+10|0;s=e[n>>1]|0;h=b[y+6>>1]<<1;r=e[m>>1]|0;q=b[y+8>>1]<<1;p=e[v>>1]|0;o=b[y+10>>1]<<1;k=2147483647;t=0;d=0;u=9716;while(1){l=(Z(h,s-(e[u>>1]|0)<<16>>16)|0)>>16;l=Z(l,l)|0;c=(Z(q,r-(e[u+2>>1]|0)<<16>>16)|0)>>16;l=(Z(c,c)|0)+l|0;c=(Z(o,p-(e[u+4>>1]|0)<<16>>16)|0)>>16;c=l+(Z(c,c)|0)|0;l=(c|0)<(k|0);d=l?t:d;t=t+1<<16>>16;if(t<<16>>16>=256)break;else{k=l?c:k;u=u+12|0}}k=(d<<16>>16)*6|0;b[n>>1]=b[9716+(k<<1)>>1]|0;b[m>>1]=b[9716+((k|1)<<1)>>1]|0;b[v>>1]=b[9716+(k+2<<1)>>1]|0;b[g+2>>1]=d;k=B+12|0;b[g+4>>1]=ue(k,16884,y+12|0,128)|0;t=w;s=x;d=v;l=B}while(0);u=a;p=B;o=u+20|0;do{b[u>>1]=b[p>>1]|0;u=u+2|0;p=p+2|0}while((u|0)<(o|0));b[z>>1]=(e[A>>1]|0)+(e[l>>1]|0);b[z+2>>1]=(e[A+2>>1]|0)+(e[t>>1]|0);b[z+4>>1]=(e[A+4>>1]|0)+(e[s>>1]|0);b[z+6>>1]=(e[A+6>>1]|0)+(e[n>>1]|0);b[z+8>>1]=(e[A+8>>1]|0)+(e[m>>1]|0);b[z+10>>1]=(e[A+10>>1]|0)+(e[d>>1]|0);b[z+12>>1]=(e[A+12>>1]|0)+(e[k>>1]|0);b[z+14>>1]=(e[A+14>>1]|0)+(e[B+14>>1]|0);b[z+16>>1]=(e[A+16>>1]|0)+(e[B+16>>1]|0);b[z+18>>1]=(e[A+18>>1]|0)+(e[B+18>>1]|0);Ae(z,205,10,j);me(z,f,10,j);i=C;return}function ue(a,c,d,f){a=a|0;c=c|0;d=d|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;t=a+2|0;u=a+4|0;v=a+6|0;if(f<<16>>16>0){m=e[a>>1]|0;n=b[d>>1]<<1;o=e[t>>1]|0;p=b[d+2>>1]<<1;q=e[u>>1]|0;r=b[d+4>>1]<<1;s=e[v>>1]|0;g=b[d+6>>1]<<1;j=2147483647;k=0;d=0;l=c;while(1){h=(Z(n,m-(e[l>>1]|0)<<16>>16)|0)>>16;h=Z(h,h)|0;i=(Z(p,o-(e[l+2>>1]|0)<<16>>16)|0)>>16;h=(Z(i,i)|0)+h|0;i=(Z(r,q-(e[l+4>>1]Line truncated
// EMSCRIPTEN_END_FUNCS
return{_free:Ke,___errno_location:Le,_memmove:Pe,_Decoder_Interface_Decode:xa,_Decoder_Interface_exit:wa,_Encoder_Interface_init:ya,_memset:Qe,_malloc:Je,_memcpy:Oe,_Encoder_Interface_exit:za,_Decoder_Interface_init:va,_Encoder_Interface_Encode:Aa,runPostSets:Ne,stackAlloc:ma,stackSave:na,stackRestore:oa,establishStackSpace:pa,setThrew:qa,setTempRet0:ta,getTempRet0:ua}})
// EMSCRIPTEN_END_ASM
(Module.asmGlobalArg,Module.asmLibraryArg,buffer);var _Encoder_Interface_Encode=Module["_Encoder_Interface_Encode"]=asm["_Encoder_Interface_Encode"];var _free=Module["_free"]=asm["_free"];var runPostSets=Module["runPostSets"]=asm["runPostSets"];var _memmove=Module["_memmove"]=asm["_memmove"];var _Decoder_Interface_exit=Module["_Decoder_Interface_exit"]=asm["_Decoder_Interface_exit"];var _Encoder_Interface_init=Module["_Encoder_Interface_init"]=asm["_Encoder_Interface_init"];var _memset=Module["_memset"]=asm["_memset"];var _malloc=Module["_malloc"]=asm["_malloc"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var _Decoder_Interface_Decode=Module["_Decoder_Interface_Decode"]=asm["_Decoder_Interface_Decode"];var _Decoder_Interface_init=Module["_Decoder_Interface_init"]=asm["_Decoder_Interface_init"];var _Encoder_Interface_exit=Module["_Encoder_Interface_exit"]=asm["_Encoder_Interface_exit"];var ___errno_location=Module["___errno_location"]=asm["___errno_location"];Runtime.stackAlloc=asm["stackAlloc"];Runtime.stackSave=asm["stackSave"];Runtime.stackRestore=asm["stackRestore"];Runtime.establishStackSpace=asm["establishStackSpace"];Runtime.setTempRet0=asm["setTempRet0"];Runtime.getTempRet0=asm["getTempRet0"];function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;var preloadStartTime=null;var calledMain=false;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};Module["callMain"]=Module.callMain=function callMain(args){assert(runDependencies==0,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");assert(__ATPRERUN__.length==0,"cannot call main when preRun functions remain to be called");args=args||[];ensureInitRuntime();var argc=args.length+1;function pad(){for(var i=0;i<4-1;i++){argv.push(0)}}var argv=[allocate(intArrayFromString(Module["thisProgram"]),"i8",ALLOC_NORMAL)];pad();for(var i=0;i<argc-1;i=i+1){argv.push(allocate(intArrayFromString(args[i]),"i8",ALLOC_NORMAL));pad()}argv.push(0);argv=allocate(argv,"i32",ALLOC_NORMAL);initialStackTop=Runtime.stackSave();try{var ret=Module["_main"](argc,argv,0);exit(ret,true)}catch(e){if(e instanceof ExitStatus){return}else if(e=="SimulateInfiniteLoop"){Module["noExitRuntime"]=true;Runtime.stackRestore(initialStackTop);return}else{if(e&&typeof e==="object"&&e.stack)Module.printErr("exception thrown: "+[e,e.stack]);throw e}}finally{calledMain=true}};function run(args){args=args||Module["arguments"];if(preloadStartTime===null)preloadStartTime=Date.now();if(runDependencies>0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(Module["_main"]&&shouldRunNow)Module["callMain"](args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=Module.run=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}if(ENVIRONMENT_IS_NODE){process["stdout"]["once"]("drain",(function(){process["exit"](status)}));console.log(" ");setTimeout((function(){process["exit"](status)}),500)}else if(ENVIRONMENT_IS_SHELL&&typeof quit==="function"){quit(status)}throw new ExitStatus(status)}Module["exit"]=Module.exit=exit;var abortDecorators=[];function abort(what){if(what!==undefined){Module.print(what);Module.printErr(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;var extra="\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";var output="abort("+what+") at "+stackTrace()+extra;if(abortDecorators){abortDecorators.forEach((function(decorator){output=decorator(output,what)}))}throw output}Module["abort"]=Module.abort=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=true;if(Module["noInitialRun"]){shouldRunNow=false}Module["noExitRuntime"]=true;run()
return AMR; })();
+1 -24
View File
@@ -6,36 +6,13 @@
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>UI Lib</title>
<script src="/amrnb.js"></script>
<script type="module" src="/main.js"></script>
<script src="/dist/ui.min.js"></script>
<script src="/dist/utility.min.js"></script>
</head>
<body>
<div id="directory">
<ul>
<li class="title">lib-ui</li>
<li>
<ol>
<li data-page="lib/ui/icon.html">icon</li>
<li data-page="lib/ui/checkbox.html">checkbox</li>
<li data-page="lib/ui/tooltip.html">tooltip</li>
<li data-page="lib/ui/dropdown.html">dropdown</li>
<li data-page="lib/ui/grid/grid.html">grid</li>
<li data-page="lib/ui/popup.html">popup</li>
</ol>
</li>
<li class="title">lib-utility</li>
<li>
<ol>
<li data-page="lib/utility/cookie.html">cookie</li>
<li data-page="lib/utility/lgres.html">lgres</li>
<li data-page="lib/utility/request.html">request</li>
<li data-page="lib/utility/strings.html">strings</li>
</ol>
</li>
</ul>
</div>
<div id="container"></div>
</body>
+10 -5
View File
@@ -155,11 +155,14 @@ class Contact {
.then(() => this.#refs.contactName.focus());
return null;
}
if (nullOrEmpty(email) && nullOrEmpty(phone)) {
showAlert(title, r('contactEmailPhoneRequired', 'Email and Mobile Phone cannot both be empty.'), 'warn')
.then(() => nullOrEmpty(email) ?
this.#refs.contactEmail.focus() :
this.#refs.contactMobile.focus());
if ((pref == 0 || pref == 2) && nullOrEmpty(phone)) {
showAlert(title, r('contactPhoneRequired', 'Mobile cannot be empty.'), 'warn')
.then(() => this.#refs.contactMobile.focus());
return null;
}
if (pref == 1 && nullOrEmpty(email)) {
showAlert(title, r('contactEmailRequired', 'Email cannot be empty.'), 'warn')
.then(() => this.#refs.contactEmail.focus());
return null;
}
if (!nullOrEmpty(email) && !isEmail(email)) {
@@ -176,6 +179,8 @@ class Contact {
contact.selected = !opt;
}
}
contact.OldName = contact.Name;
contact.OldMobilePhone = contact.MobilePhone;
contact.Name = name;
contact.ContactPreference = pref;
contact.Email = email;
+2 -4
View File
@@ -10,6 +10,8 @@ interface InitConfig {
}
export class CustomerCommunication {
constructor (opt: InitConfig);
get autoUpdatesEnabled(): boolean;
set autoUpdatesEnabled(enabled: boolean);
get autoUpdates(): boolean;
@@ -22,7 +24,3 @@ export class CustomerCommunication {
create(): HTMLElement;
}
declare var CustomerCommunication: {
new(opt: InitConfig): CustomerCommunication
}
+63 -21
View File
@@ -1,10 +1,10 @@
import { Grid, createElement, setTooltip, createIcon, createCheckbox, createRadiobox, showAlert, showConfirm, Popup } from "../../ui";
import { Grid, GridColumn, createElement, setTooltip, createIcon, createCheckbox, createRadiobox, showAlert, showConfirm, Popup, createPicture, createAudio, createVideo, createPdf, createSmilefile, createVcard, createVideofile, createFile } from "../../ui";
import { r, nullOrEmpty, formatUrl, isEmail, isPhone } from "../../utility";
import { createBox } from "./lib";
import { Contact, CustomerRecordContact } from "./contact";
import Follower from "./follower";
class NoteCol extends Grid.GridColumn {
class NoteCol extends GridColumn {
static create() {
const wrapper = createElement('div', 'contact-wrapper',
createElement('div', 'contact-name'),
@@ -19,7 +19,12 @@ class NoteCol extends Grid.GridColumn {
if (name.scrollWidth > name.offsetWidth) {
setTooltip(name, item.Name, false, grid.element);
}
element.querySelector('.contact-note').innerText = item.Notes;
const notes = element.querySelector('.contact-note');
notes.innerText = item.Notes;
if (notes.scrollWidth > notes.offsetWidth) {
setTooltip(notes, item.Notes, false, grid.element);
}
}
}
@@ -243,14 +248,15 @@ class CustomerCommunication {
* @param {String} code
*/
set companyCode(code) {
this.#option.companyCode = code;
const option = this.#option;
option.companyCode = code;
const div = this.#container.querySelector('.title-company');
if (nullOrEmpty(this.#option.companyName)) {
if (nullOrEmpty(option.companyName)) {
div.style.display = 'none';
} else {
div.innerText = this.#option.companyName;
div.innerText = option.companyName;
if (!nullOrEmpty(code))
div.innerText = this.#option.companyName + "/" + code;
div.innerText = option.companyName + "/" + code;
div.style.display = '';
}
}
@@ -432,11 +438,15 @@ class CustomerCommunication {
button.addEventListener('click', () => {
const val = this.#enter.value;
if (nullOrEmpty(val?.trim())) {
showAlert(r('error', 'Error'), r('messageRequired', 'Please input the message.'), 'warn');
const p = showAlert(r('error', 'Error'), r('messageRequired', 'Please input the message.'), 'warn');
if (typeof option.onMasking === 'function') {
option.onMasking(true);
p.then(() => option.onMasking(false));
}
return;
}
if (typeof this.#option.onAddMessage === 'function') {
this.#option.onAddMessage(this.#enter.value);
if (typeof option.onAddMessage === 'function') {
option.onAddMessage(this.#enter.value);
}
})
})
@@ -514,12 +524,12 @@ class CustomerCommunication {
// onMasking: option.onMasking,
contacts: [],
onOk: list => {
if (typeof this.#option.onSelectCRContacts === 'function') {
if (typeof option.onSelectCRContacts === 'function') {
list?.map(c => {
delete c.selected;
return c;
});
const result = this.#option.onSelectCRContacts(list);
const result = option.onSelectCRContacts(list);
}
const r = this.#data.contacts;
this.#gridContact.source = r.filter(c => c.Id >= 0).map(c => {
@@ -545,8 +555,8 @@ class CustomerCommunication {
var title = r('selectFromCustomerRecord', 'Select from Customer Record');
sel.show(title, container);
if (typeof this.#option.onOpenSelectCRContacts === 'function') {
const result = this.#option.onOpenSelectCRContacts();
if (typeof option.onOpenSelectCRContacts === 'function') {
const result = option.onOpenSelectCRContacts();
if (typeof result?.then === 'function') {
return result.then(r => {
r.map(c => {
@@ -595,7 +605,7 @@ class CustomerCommunication {
button.addEventListener('click', () => {
const add = new Contact({
// onMasking: option.onMasking,
company: !nullOrEmpty(this.#option.companyName),
company: !nullOrEmpty(option.companyName),
onSave: item => {
const exists = this.#gridContact.source.some(s => s.Name === item.Name && s.MobilePhone === item.MobilePhone);
if (exists) {
@@ -639,14 +649,14 @@ class CustomerCommunication {
}),
content: createElement('div', null,
createElement('div', div => {
if (nullOrEmpty(this.#option.companyName)) {
if (nullOrEmpty(option.companyName)) {
div.style.display = 'none';
}
div.style.fontWeight = 'bold';
div.innerText = r('contactFromRecord', 'Contacts from Customer Record');
}),
createElement('div', div => {
if (nullOrEmpty(this.#option.companyName)) {
if (nullOrEmpty(option.companyName)) {
div.style.display = 'none';
}
div.className = 'contacts-record';
@@ -952,8 +962,8 @@ class CustomerCommunication {
button.appendChild(createIcon('fa-solid', 'pen'));
setTooltip(button, r('editFollower', 'Edit Followers'));
button.addEventListener('click', () => {
if (typeof this.#option.onInitFollower === 'function') {
this.#option.onInitFollower(this.#data.followers).then(data => {
if (typeof option.onInitFollower === 'function') {
option.onInitFollower(this.#data.followers).then(data => {
if (typeof data === 'string') {
showAlert(r('customerRecord', 'Customer Record'), data, 'warn');
return;
@@ -962,8 +972,8 @@ class CustomerCommunication {
onMasking: option.onMasking,
followers: data,
onOk: list => {
if (typeof this.#option.onAddFollower === 'function') {
const result = this.#option.onAddFollower(list);
if (typeof option.onAddFollower === 'function') {
const result = option.onAddFollower(list);
if (typeof result?.then === 'function') {
return result.then(r => {
// this.followers = r;
@@ -1060,6 +1070,38 @@ class CustomerCommunication {
span.innerText = comm.Message;
}
}));
if (comm.IsMMS && comm.MMSParts?.length > 0) {
for (let kv of comm.MMSParts) {
switch (kv.Key) {
case 'application/pdf':
content.appendChild(createPdf(kv.Value));
break;
case 'application/smil':
content.appendChild(createSmilefile(kv.Value));
break;
case 'audio/amr':
content.appendChild(createAudio(kv.Key));
break;
case 'image/gif':
case 'image/jpeg':
case 'image/png':
content.appendChild(createPicture(kv.Value));
break;
case 'text/x-vcard':
content.appendChild(createVcard(kv.Value));
break;
case 'video/3gpp':
content.appendChild(createVideofile(kv.Value));
break;
case 'video/mp4':
content.appendChild(createVideo(kv.Value));
break;
default:
content.appendChild(createFile(kv.Value));
break;
}
}
}
if (comm.IsReply) {
div.classList.add('item-other');
} else {
+7 -1
View File
@@ -1 +1,7 @@
export function createElement<K extends keyof HTMLElementTagNameMap>(tagName: K, init?: string | ((element: HTMLElementTagNameMap[K]) => void), ...children?: (Node | string)[]): HTMLElementTagNameMap[K];
/**
* 创建一个 html 元素
* @param tagName 标签名
* @param init 样式类名,或者为有一个 html 元素作为参数的函数
* @param children 子元素
*/
export function createElement<K extends keyof HTMLElementTagNameMap>(tagName: K, init?: string | ((element: HTMLElementTagNameMap[K]) => void), ...children: (Node | string)[]): HTMLElementTagNameMap[K];
+21 -5
View File
@@ -4,10 +4,11 @@ import { createElement } from "./functions";
import { createIcon, changeIcon, resolveIcon } from "./ui/icon";
import { createCheckbox, createRadiobox, resolveCheckbox } from "./ui/checkbox";
import { setTooltip, resolveTooltip } from "./ui/tooltip";
import Dropdown from "./ui/dropdown";
import Grid from "./ui/grid/grid";
import Popup from "./ui/popup";
import { createPopup, showAlert, showConfirm } from "./ui/popup";
import { Dropdown } from "./ui/dropdown";
import { Grid } from "./ui/grid/grid";
import { GridColumn, GridInputColumn, GridDropdownColumn, GridCheckboxColumn, GridIconColumn, GridTextColumn } from './ui/grid/column';
import { Popup, createPopup, showAlert, showConfirm } from "./ui/popup";
import { createPicture, createAudio, createVideo, createPdf, createSmilefile, createVcard, createVideofile, createFile } from './ui/media';
export {
createElement,
@@ -26,9 +27,24 @@ export {
Dropdown,
// grid
Grid,
GridColumn,
GridInputColumn,
GridDropdownColumn,
GridCheckboxColumn,
GridIconColumn,
GridTextColumn,
// popup
Popup,
createPopup,
showAlert,
showConfirm
showConfirm,
// media
createPicture,
createAudio,
createVideo,
createPdf,
createSmilefile,
createVcard,
createVideofile,
createFile
}
+33 -1
View File
@@ -1,18 +1,50 @@
/**
* 复选框选项
*/
interface CheckboxOptions {
/** 样式类名 */
className?: string;
/** 是否可用 */
enabled?: boolean;
/** html 名称 */
name?: string;
/** 焦点索引 */
tabIndex?: Number;
/** 样式分类,可以是 ['`fa-light`', '`fa-regular`', '`fa-solid`'] 其中之一 */
type?: string;
/** 标签 */
label?: string | HTMLElement;
/** 是否已选中 */
checked?: boolean;
/** 图片高度 */
imageHeight?: Number;
/** 选中时显示的元素 */
checkedNode?: HTMLElement;
/** 未选中时显示的元素 */
uncheckedNode?: HTMLElement;
customerAttributes?: { [key: string]: string };
/** 自定义 html 属性 */
customAttributes?: { [key: string]: string };
/**
* 复选框选择状态改变时触发
* @param this 当前复选框对应的 HtmlInput 元素
* @param ev 选择事件对象
*/
onchange?: (this: HTMLInputElement, ev: Event) => any;
}
/**
* 创建一个单选框
* @param opts 单选框参数
*/
export function createRadiobox(opts?: CheckboxOptions): HTMLElement
/**
* 创建一个复选框
* @param opts 复选框参数
*/
export function createCheckbox(opts?: CheckboxOptions): HTMLElement
/**
* 解析容器元素内符合条件的子元素为复选框元素
* @param container 容器元素
* @param legacy 是否使用传统模式
*/
export function resolveCheckbox(container?: HTMLElement, legacy?: boolean): HTMLElement
-138
View File
@@ -1,138 +0,0 @@
<div>
<h1>checkbox</h1>
<hr />
<p>
创建一个统一样式的复选框元素,或者解析转换页面上特定类型的 label
标签为复选框元素。
</p>
<h2>createCheckbox</h2>
<code>function createCheckbox(opts?: CheckboxOptions): HTMLElement</code>
<h3>opts?: CheckboxOptions</h3>
<p>
复选框初始参数,结构为
<pre>interface CheckboxOptions {
className?: string;
enabled?: boolean;
name?: string;
tabIndex?: Number;
type?: string;
label?: string;
checked?: boolean;
imageHeight?: Number;
checkedNode?: HTMLElement;
uncheckedNode?: HTMLElement;
customerAttributes?: { [key: string]: string };
onchange?: (this: HTMLInputElement, ev: Event) => any;
}</pre>
</p>
<h4>className?: string</h4>
<p>
复选框的自定义 className
</p>
<h4>enabled?: boolean</h4>
<p>
复选框默认是否可用
</p>
<h4>name?: string</h4>
<p>
复选框或单选框的 name
</p>
<h4>tabIndex?: Number</h4>
<p>
复选框的 tabindex
</p>
<h4>type?: string</h4>
<p>
复选框图标的样式,可选值目前有 <code>fa-regular</code>、<code>fa-light</code>、<code>fa-solid</code>
</p>
<h4>label?: string | HTMLElement</h4>
<p>
复选框的标签文本,或者想要呈现的元素
</p>
<h4>checked?: boolean</h4>
<p>
初始是否选中
</p>
<h4>imageHeight?: Number</h4>
<p>
为图片复选框时的图片限制高度
</p>
<h4>checkedNode?: HTMLElement</h4>
<p>
为图片复选框时的选中时显示的元素
</p>
<h4>uncheckedNode?: HTMLElement</h4>
<p>
为图片复选框时的未选中时显示的元素
</p>
<h4>customerAttributes?: { [key: string]: string }</h4>
<p>
自定义属性,例如
<pre>{
'data-id': 'xxxxxx',
'disabled': ''
}</pre>
</p>
<h4>onchange?: (this: HTMLInputElement, ev: Event) => any</h4>
<p>
复选框改变时触发的事件
</p>
<h2>createRadiobox</h2>
<code>function createRadiobox(opts?: CheckboxOptions): HTMLElement</code>
<h3>opts?: CheckboxOptions</h3>
<p>
单选框初始参数,结构如上
</p>
<h2>resolveCheckbox</h2>
<code>function resolveCheckbox(container?: HTMLElement, legacy?: boolean): HTMLElement</code>
<h3>container?: HTMLElement</h3>
<p>
将把此 HTML 元素,为 null 则把 document.body 下的所有 <code>label[data-checkbox]</code> 元素解析为复选框,<code>[data-id]</code> 为复选框元素的
id,包含
<code>[data-checked]</code> 时复选框默认选中。
</p>
<p>当该元素无子元素时,<code>[data-type]</code> 同上述参数中的 <code>type?: string</code>,<code>[data-label]</code> 同上述参数中的
<code>label?: string</code>。
</p>
<p>当该元素有子元素时,解析为图片复选框,class 为 <code>checked</code>、<code>unchecked</code> 的子元素将分别在选中与未选中时显示。</p>
<h3>legacy?: boolean</h3>
<p>
是否开启兼容模式,启用兼容模式时将试图匹配 <code>input[type="checkbox"]</code> 标签,与其周围的 label,将其转换为统一样式的复选框。
</p>
<hr />
<h2>示例</h2>
<pre>&lt;div id="checkbox-sample"&gt;
&lt;!-- 1 --&gt;
&lt;label data-checkbox data-type="fa-light" data-label="Checkbox Light"&gt;&lt;/label&gt;
&lt;!-- 2 --&gt;
&lt;label data-checkbox data-checked data-label="Checkbox Regular"&gt;&lt;/label&gt;
&lt;!-- 3 --&gt;
&lt;label data-checkbox data-type="fa-solid" data-label="Checkbox Solid"&gt;&lt;/label&gt;
&lt;!-- 4 --&gt;
&lt;label data-checkbox&gt;
&lt;code class="checked"&gt;Checked&lt;/code&gt;
&lt;code class="unchecked"&gt;Unchecked&lt;/code&gt;
&lt;/label&gt;
&lt;!-- 5 --&gt;
&lt;input id="check-status" type="checkbox"/&gt;
&lt;label for="check-status"&gt;Label for Status&lt;/label&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
window["lib-ui"].resolveCheckbox(document.querySelector("#checkbox-sample"), true);
&lt;/script&gt;</pre>
<div id="checkbox-sample">
<label data-checkbox data-type="fa-light" data-label="Checkbox Light"></label>
<label data-checkbox data-checked data-label="Checkbox Regular"></label>
<label data-checkbox data-type="fa-solid" data-label="Checkbox Solid"></label>
<label data-checkbox>
<code class="checked">Checked</code>
<code class="unchecked">Unchecked</code>
</label>
<input id="check-status" type="checkbox" />
<label for="check-status">Label for Status</label>
</div>
<script type="text/javascript">
window["lib-ui"].resolveCheckbox(document.querySelector("#checkbox-sample"), true);
</script>
</div>
+4 -4
View File
@@ -40,8 +40,8 @@ function createRadiobox(opts = {}) {
if (opts.enabled === false) {
input.disabled = true;
}
if (opts.customerAttributes != null) {
for (let entry of Object.entries(opts.customerAttributes)) {
if (opts.customAttributes != null) {
for (let entry of Object.entries(opts.customAttributes)) {
input.setAttribute(entry[0], entry[1]);
}
}
@@ -66,8 +66,8 @@ function createCheckbox(opts = {}) {
if (opts.enabled === false) {
input.disabled = true;
}
if (opts.customerAttributes != null) {
for (let entry of Object.entries(opts.customerAttributes)) {
if (opts.customAttributes != null) {
for (let entry of Object.entries(opts.customAttributes)) {
input.setAttribute(entry[0], entry[1]);
}
}
+60
View File
@@ -0,0 +1,60 @@
.ui-media-picture>img {
max-width: 100px;
max-height: 100px;
}
.ui-media-file {
display: inline-flex;
align-items: center;
>svg {
width: 26px;
height: 26px;
fill: var(--link-color);
}
>a {
margin-left: 6px;
color: var(--link-color);
font-size: var(--font-size);
}
}
.ui-media-audio {
display: inline-flex;
align-items: center;
background-color: #eee;
border-radius: 20px;
overflow: hidden;
padding-right: 16px;
>button {
background-color: transparent;
border: none;
width: 40px;
height: 40px;
padding: 14px;
display: flex;
outline: none;
&:hover {
border: none;
}
>svg {
width: 100%;
height: 100%;
}
}
>.ui-media-timestamp {
color: var(--secondary-color);
font-size: var(--font-size);
user-select: none;
}
}
.ui-media-video {
max-width: 200px;
max-height: 200px;
}
+1
View File
@@ -13,6 +13,7 @@
/*color-scheme: light dark;*/
--color: #201f1e;
--secondary-color: #777;
--bg-color: #fff;
--border-color: #b9b9b9;
--focus-border-color: #666;
+5 -10
View File
@@ -23,7 +23,11 @@ export interface DropdownOptions {
parent?: HTMLElement;
}
interface Dropdown {
export class Dropdown {
static resolve(dom?: HTMLElement): HTMLElement;
constructor(options?: DropdownOptions);
sourceFilter: () => Array<DropdownItem | any>;
onselected: (item: DropdownItem | any) => void;
onselectedlist: (list: Array<DropdownItem | any>) => void;
@@ -40,12 +44,3 @@ interface Dropdown {
select(selected: string, silence?: boolean): void;
selectlist(selectedlist: Array<string>, silence?: boolean): void;
}
declare var Dropdown: {
prototype: Dropdown;
new(options?: DropdownOptions): Dropdown;
resolve(dom?: HTMLElement): HTMLElement;
}
export default Dropdown;
-304
View File
@@ -1,304 +0,0 @@
<div>
<h1>dropdown</h1>
<hr />
<p>
创建一个统一样式的下拉输入、选择框元素,或者解析转换页面上的 select 标签为该元素。
</p>
<h2>constructor</h2>
<code>new(options?: DropdownOptions): Dropdown</code>
<h3>options?: DropdownOptions</h3>
<p>
下拉输入、选择框的初始参数,结构为
<pre>interface DropdownOptions {
textkey?: string;
valuekey?: string;
htmlkey?: string;
maxlength?: Number;
multiselect?: boolean;
selected?: string;
selectedlist?: Array&lt;DropdownItem | any&gt;;
disabled?: boolean;
input?: boolean;
search?: boolean;
searchkeys?: Array&lt;string&gt;;
searchplaceholder?: string;
tabindex?: Number;
placeholder?: string;
slidefixed?: boolean;
parent?: HTMLElement;
}</pre>
</p>
<h4>textkey?: string</h4>
<p>
数据源中用以显示的属性,默认为 <code>text</code>
</p>
<h4>valuekey?: string</h4>
<p>
数据源中作为值的属性,默认为 <code>value</code>
</p>
<h4>htmlkey?: string</h4>
<p>
数据源中用来以 html 方式呈现的属性,默认为 <code>html</code>
</p>
<h4>maxlength?: Number</h4>
<p>
作为输入类型时的最大允许字符数,默认为 500
</p>
<h4>multiselect?: boolean</h4>
<p>
是否允许多选,仅在选择类型下有效
</p>
<h4>selected?: string</h4>
<p>
默认选中的项目的值
</p>
<h4>selectedlist?: Array&lt;DropdownItem | any&gt;</h4>
<p>
多选时默认选中的项目的值的列表
</p>
<h4>disabled?: boolean</h4>
<p>
初始化时下拉框是否禁用
</p>
<h4>input?: boolean</h4>
<p>
是否为输入类型
</p>
<h4>search?: boolean</h4>
<p>
是否允许搜索
</p>
<h4>searchkeys?: Array&lt;string&gt;</h4>
<p>
搜索时搜索的数据源属性的列表,默认为 <code>[valuekey]</code>
</p>
<h4>searchplaceholder?: string</h4>
<p>
搜索输入框的占位字符串
</p>
<h4>tabindex?: Number</h4>
<p>
下拉框的焦点顺序
</p>
<h4>placeholder?: string</h4>
<p>
作为输入类型时,输入框的占位字符串
</p>
<h4>slidefixed?: boolean</h4>
<p>
下拉方向是否固定为下
</p>
<h4>parent?: HTMLElement</h4>
<p>
下拉列表呈现的父容器,默认为 <code>document.body</code>
</p>
<h2>Dropdown.resolve</h2>
<code>static resolve(dom?: HTMLElement): HTMLElement</code>
<h3>dom?: HTMLElement</h3>
<p>
将把此 HTML 元素,为 null 则把 document.body 下的所有 <code>select</code> 元素解析为统一样式的下拉框
</p>
<hr />
<h2>sourceFilter</h2>
<code>sourceFilter: () => Array&lt;DropdownItem | any&gt;</code>
<p>
数据源代理,返回用以呈现在下拉列表中的数据源
</p>
<h2>onselected</h2>
<code>onselected: (item: DropdownItem | any) => void</code>
<h3>item: DropdownItem | any</h3>
<p>
选中项发生改变时触发该事件,参数为选中的项
</p>
<h2>onselectedlist</h2>
<code>onselectedlist: (list: Array&lt;DropdownItem | any&gt;) => void</code>
<h3>list: Array&lt;DropdownItem | any&gt;</h3>
<p>
多选时选中列表发生改变时触发该事件,参数为选中的列表
</p>
<h2>onexpanded</h2>
<code>onexpanded: () => void</code>
<p>
下拉列表展开时触发该事件,一般用来异步获取服务器数据,填充至数据源
</p>
<hr />
<h2>disabled</h2>
<code>property disabled(): boolean</code>
<p>
获取或设置下拉框是否禁用
</p>
<h2>source</h2>
<code>property source(): Array&lt;DropdownItem | any&gt;</code>
<p>
获取或设置下拉框数据源
</p>
<h2>multiselect</h2>
<code>readonly multiselect: boolean</code>
<p>
获取下拉框是否支持多选
</p>
<h2>selected</h2>
<code>readonly selected: DropdownItem | any</code>
<p>
获取下拉框当前选中项
</p>
<h2>selectedlist</h2>
<code>readonly selectedlist: Array&lt;DropdownItem | any&gt;</code>
<p>
获取下拉框当前选中的列表
</p>
<hr />
<h2>create</h2>
<code>create(): HTMLElement</code>
<p>
创建下拉列表,返回一个 HTML 元素
</p>
<h2>select</h2>
<code>select(selected: string, silence?: boolean): void</code>
<h3>selected: string</h3>
<p>
修改下拉框的选中项为参数值对应的项
</p>
<h3>silence?: boolean</h3>
<p>
是否静默修改,为 true 时不触发 <code>onselected</code> 事件
</p>
<h2>selectlist</h2>
<code>selectlist(selectedlist: Array&lt;string&gt;, silence?: boolean): void</code>
<h3>selectedlist: Array&lt;string&gt;</h3>
<p>
修改下拉框的选中列表为参数值列表对应的项的列表
</p>
<h3>silence?: boolean</h3>
<p>
是否静默修改,为 true 时不触发 <code>onselectedlist</code> 事件
</p>
<hr />
<h2>示例</h2>
<pre>&lt;div id="dropdown-sample"&gt;
&lt;select&gt;
&lt;option value="cs1"&gt;Case 1&lt;/option&gt;
&lt;option value="cs2" selected&gt;Case 2&lt;/option&gt;
&lt;option value="cs3"&gt;Case 3&lt;/option&gt;
&lt;/select&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
const Dropdown = window["lib-ui"].Dropdown;
const sample = document.querySelector('#dropdown-sample');
// 解析 select 元素
Dropdown.resolve(sample);
// 创建简易输入类型下拉框
let drop = new Dropdown({
input: true,
// selected: 'standby',
placeholder: 'asset status',
slidefixed: true
});
drop.source = ['off', 'running', 'standby', 'broken']
.map(it => { return { value: it, text: it } });
sample.appendChild(drop.create());
// 创建自定义显示元素的下拉框
drop = new Dropdown({
selected: '#ff0',
search: true,
// multiselect: true
});
drop.source = [
{ value: '#fff', text: 'White' },
{ value: '#f00', text: 'Red' },
{ value: '#0f0', text: 'Green' },
{ value: '#00f', text: 'Blue' },
{ value: '#ff0', text: 'Yellow' },
{ value: '#0ff', text: 'Cyan' },
{ value: '#f0f', text: 'Magenta' },
];
drop.source.forEach(it => {
const span = document.createElement('span');
span.className = 'ui-drop-item';
span.style.setProperty('--color', it.value);
span.innerText = it.text;
it.html = span;
});
sample.appendChild(drop.create());
&lt;/script&gt;</pre>
<div id="dropdown-sample">
<select>
<option value="cs1">Case 1</option>
<option value="cs2" selected>Case 2</option>
<option value="cs3">Case 3</option>
</select>
</div>
<div style="height: 80px"></div>
<script type="text/javascript">
!function () {
const Dropdown = window["lib-ui"].Dropdown;
const sample = document.querySelector('#dropdown-sample');
Dropdown.resolve(sample);
let drop = new Dropdown({
input: true,
// selected: 'standby',
placeholder: 'asset status',
slidefixed: true
});
drop.source = ['off', 'running', 'standby', 'broken']
.map(it => { return { value: it, text: it } });
sample.appendChild(drop.create());
drop = new Dropdown({
selected: '#ff0',
search: true,
// multiselect: true
});
drop.source = [
{ value: '#fff', text: 'White' },
{ value: '#f00', text: 'Red' },
{ value: '#0f0', text: 'Green' },
{ value: '#00f', text: 'Blue' },
{ value: '#ff0', text: 'Yellow' },
{ value: '#0ff', text: 'Cyan' },
{ value: '#f0f', text: 'Magenta' },
];
drop.source.forEach(it => {
const span = document.createElement('span');
span.className = 'ui-drop-item';
span.style.setProperty('--color', it.value);
span.innerText = it.text;
it.html = span;
});
sample.appendChild(drop.create());
}();
</script>
<style type="text/css">
#dropdown-sample {
display: flex;
}
#dropdown-sample>.ui-drop-wrapper {
width: 200px;
margin-right: 10px;
}
.ui-drop-item {
font-size: .75rem !important;
padding: 0 0 0 22px !important;
position: relative;
}
.ui-drop-item::before {
content: '';
position: absolute;
width: 12px;
height: 12px;
border-radius: 6px;
top: calc(50% - 6px);
left: 6px;
background-color: var(--color);
}
</style>
</div>
+3 -5
View File
@@ -81,7 +81,7 @@ function filterSource(searchkeys, textkey, key, source) {
return source;
}
class Dropdown {
export class Dropdown {
#options;
#wrapper;
@@ -412,7 +412,7 @@ class Dropdown {
createCheckbox({
label: r('allItem', '( All )'),
checked: allchecked,
customerAttributes: { 'isall': '1' },
customAttributes: { 'isall': '1' },
onchange: e => this.#triggerselect(e.target)
})
)
@@ -444,7 +444,7 @@ class Dropdown {
const box = createCheckbox({
label,
checked: allchecked || selected,
customerAttributes: {
customAttributes: {
'class': 'dataitem',
'data-value': val
},
@@ -528,5 +528,3 @@ class Dropdown {
return dom;
}
}
export default Dropdown;
+61
View File
@@ -0,0 +1,61 @@
import { Grid, GridItem, GridSourceItem } from "./grid";
import { DropdownOptions } from "../dropdown";
interface GridColumnType {
0: "Common";
1: "Input";
2: "Dropdown";
3: "Checkbox";
4: "Icon";
5: "Text";
}
export interface GridColumnDefinition {
key?: string;
type?: keyof GridColumnType | typeof GridColumn;
caption?: string;
width?: Number;
align?: "left" | "center" | "right";
enabled?: boolean | string | ((item: GridItem | any) => boolean);
css?: { [key: string]: string };
styleFilter?: (item: GridItem | any) => { [key: string]: string };
textStyle?: { [key: string]: string };
visible?: boolean;
resizable?: boolean;
sortable?: boolean;
orderable?: boolean;
allcheck?: boolean;
events?: { [event: string]: any };
attrs?: { [key: string]: string } | ((item: GridItem | any) => { [key: string]: string });
allowFilter?: boolean;
filter?: (item: GridItem | any) => any;
sortFilter?: (a: GridItem | any, b: GridItem | any) => -1 | 0 | 1;
bgFilter?: (item: GridItem | any) => string;
dropOptions?: DropdownOptions;
source?: Array<any> | ((item: GridItem | any) => Array<any> | Promise<Array<GridSourceItem>>);
iconType?: string;
className?: string | ((item: GridItem | any) => string);
text?: string;
tooltip?: string;
onallchecked?: (this: Grid, col: GridColumnDefinition, flag: boolean) => void;
onchanged?: (this: Grid, item: GridItem | any, value: boolean | any) => void;
}
export class GridColumn {
create(): HTMLElement;
createEdit(trigger: (e: any) => void, col: GridColumnDefinition, body: HTMLElement): HTMLElement;
setValue(element: HTMLElement, val: any, item: GridItem | any, col: GridColumnDefinition): void;
getValue(e: any): any;
setStyle(element: HTMLElement, style: { [key: string]: string }): void;
setEnabled(element: HTMLElement, enabled?: boolean): void;
}
export class GridInputColumn extends GridColumn { }
export class GridTextColumn extends GridInputColumn { }
export class GridDropdownColumn extends GridColumn { }
export class GridCheckboxColumn extends GridColumn { }
export class GridIconColumn extends GridColumn { }
+7 -16
View File
@@ -4,9 +4,9 @@ import { createElement } from "../../functions";
import { createIcon } from "../icon";
import { createCheckbox } from "../checkbox";
// import { setTooltip } from "../tooltip";
import Dropdown from "../dropdown";
import { Dropdown } from "../dropdown";
class GridColumn {
export class GridColumn {
static create() {
return createElement('span');
}
@@ -29,7 +29,7 @@ class GridColumn {
}
}
class GridInputColumn extends GridColumn {
export class GridInputColumn extends GridColumn {
static get editing() { return true };
static createEdit(trigger, col, _parent, vals) {
@@ -66,7 +66,7 @@ class GridInputColumn extends GridColumn {
}
}
class GridTextColumn extends GridInputColumn {
export class GridTextColumn extends GridInputColumn {
static createEdit(trigger, col, _parent, vals) {
const input = createElement('textarea');
if (typeof trigger === 'function') {
@@ -100,7 +100,7 @@ class GridTextColumn extends GridInputColumn {
const SymbolDropdown = Symbol.for('ui-dropdown');
class GridDropdownColumn extends GridColumn {
export class GridDropdownColumn extends GridColumn {
static createEdit(trigger, col, parent) {
const drop = new Dropdown({ ...col.dropOptions, parent });
drop.onselected = trigger;
@@ -179,7 +179,7 @@ class GridDropdownColumn extends GridColumn {
}
}
class GridCheckboxColumn extends GridColumn {
export class GridCheckboxColumn extends GridColumn {
static createEdit(trigger) {
const check = createCheckbox({
onchange: typeof trigger === 'function' ? trigger : null
@@ -199,7 +199,7 @@ class GridCheckboxColumn extends GridColumn {
}
}
class GridIconColumn extends GridColumn {
export class GridIconColumn extends GridColumn {
static create() { return createElement('span', 'col-icon') }
static setValue(element, val, item, col, grid) {
@@ -236,12 +236,3 @@ class GridIconColumn extends GridColumn {
}
}
}
export {
GridColumn,
GridInputColumn,
GridTextColumn,
GridDropdownColumn,
GridCheckboxColumn,
GridIconColumn
}
+16 -69
View File
@@ -1,64 +1,15 @@
import { DropdownOptions } from "../dropdown";
import { GridColumnDefinition } from "./column"
interface GridItem {
export interface GridItem {
value: any;
displayValue: string;
}
interface GridSourceItem {
export interface GridSourceItem {
value: string;
text: string;
}
declare var GridColumn: {
create(): HTMLElement;
createEdit(trigger: (e: any) => void, col: GridColumnDefinition, body: HTMLElement): HTMLElement;
setValue(element: HTMLElement, val: any, item: GridItem | any, col: GridColumnDefinition): void;
getValue(e: any): any;
setStyle(element: HTMLElement, style: { [key: string]: string }): void;
setEnabled(element: HTMLElement, enabled?: boolean): void;
}
interface GridColumnType {
0: "Common";
1: "Input";
2: "Dropdown";
3: "Checkbox";
4: "Icon";
5: "Text";
}
interface GridColumnDefinition {
key?: string;
type?: keyof GridColumnType | typeof GridColumn;
caption?: string;
width?: Number;
align?: "left" | "center" | "right";
enabled?: boolean | string | ((item: GridItem | any) => boolean);
css?: { [key: string]: string };
styleFilter?: (item: GridItem | any) => { [key: string]: string };
textStyle?: { [key: string]: string };
visible?: boolean;
resizable?: boolean;
sortable?: boolean;
orderable?: boolean;
allcheck?: boolean;
events?: { [event: string]: any };
attrs?: { [key: string]: string } | ((item: GridItem | any) => { [key: string]: string });
allowFilter?: boolean;
filter?: (item: GridItem | any) => any;
sortFilter?: (a: GridItem | any, b: GridItem | any) => -1 | 0 | 1;
bgFilter?: (item: GridItem | any) => string;
dropOptions?: DropdownOptions;
source?: Array<any> | ((item: GridItem | any) => Array<any> | Promise<Array<GridSourceItem>>);
iconType?: string;
className?: string | ((item: GridItem | any) => string);
text?: string;
tooltip?: string;
onallchecked?: (this: Grid, col: GridColumnDefinition, flag: boolean) => void;
onchanged?: (this: Grid, item: GridItem | any, value: boolean | any) => void;
}
interface GridColumnDirection {
[-1]: Number,
1: Number
@@ -70,7 +21,17 @@ interface GridColumnColumnEventMap {
"sort": string
}
interface Grid {
export class Grid {
static ColumnTypes: {
Common: 0,
Input: 1,
Dropdown: 2,
Checkbox: 3,
Icon: 4,
Text: 5,
isCheckbox(type: Number): boolean;
};
columns: Array<GridColumnDefinition>;
langs?: { all: string, ok: string, reset: string };
virtualCount?: Number;
@@ -88,6 +49,8 @@ interface Grid {
sortIndex?: Number;
sortDirection?: keyof GridColumnDirection;
constructor(container: HTMLElement);
willSelect?: (index: Number, colIndex: Number) => boolean;
selectedRowChanged?: (index?: Number) => void;
cellDblClicked?: (index: Number, colIndex: Number) => void;
@@ -116,19 +79,3 @@ interface Grid {
resetChange(): void;
sortColumn(reload?: boolean): void;
}
declare var Grid: {
ColumnTypes: {
Common: 0,
Input: 1,
Dropdown: 2,
Checkbox: 3,
Icon: 4,
Text: 5,
isCheckbox(type: Number): boolean;
};
GridColumn: typeof GridColumn;
new(container: HTMLElement): Grid;
}
export default Grid;
-277
View File
@@ -1,277 +0,0 @@
<div>
<h1>grid</h1>
<hr />
<p>
创建一个统一样式的滚动列表元素。
</p>
<h2>constructor</h2>
<code>new(container: HTMLElement): Grid</code>
<h3>container: HTMLElement</h3>
<p>
父容器元素,Grid 将创建在此元素之内
</p>
<h2>init</h2>
<code>init(container?: HTMLElement): void</code>
<h3>container?: HTMLElement</h3>
<p>
父容器元素,默认使用构造函数中传递的值
</p>
<h2>scrollToIndex</h2>
<code>scrollToIndex(index: Number): void</code>
<h3>index: Number</h3>
<p>
将滚动至此行
</p>
<h2>resize</h2>
<code>resize(force?: boolean): void</code>
<h3>force?: boolean</h3>
<p>
重新计算大小,参数表示是否强制重载
</p>
<h2>reload</h2>
<code>reload(): void</code>
<p>
重载表格元素
</p>
<h2>refresh</h2>
<code>refresh(): void</code>
<p>
刷新表格单元格值
</p>
<h2>resetChange</h2>
<code>resetChange(): void</code>
<p>
还原表格修改状态,置为未修改
</p>
<h2>sortColumn</h2>
<code>sortColumn(reload?: boolean): void</code>
<h3>reload?: boolean</h3>
<p>
根据当前设定的排序列排序,参数表示是否重载表格
</p>
<hr />
<h2>sortIndex</h2>
<code>sortIndex?: Number</code>
<p>
排序的列序号
</p>
<h2>sortDirection</h2>
<code>sortDirection?: keyof GridColumnDirection</code>
<p>
排序的方向,可选值为 <code>-1: desc</code>、<code>1: asc</code>
</p>
<h2>columns</h2>
<code>columns: Array&lt;GridColumnDefinition&gt;</code>
<p>
表格列的定义,结构为
<pre>interface GridColumnDefinition {
key?: string;
type?: keyof GridColumnType | typeof GridColumn;
caption?: string;
width?: Number;
align?: "left" | "center" | "right";
enabled?: boolean | string;
css?: { [key: string]: string };
styleFilter?: (item: GridItem | any) => { [key: string]: string };
textStyle?: { [key: string]: string };
visible?: boolean;
resizable?: boolean;
sortable?: boolean;
orderable?: boolean;
allcheck?: boolean;
events?: { [event: string]: any };
attrs?: { [key: string]: string } | ((item: GridItem | any) => { [key: string]: string });
filter?: (item: GridItem | any) => any;
sortFilter?: (a: GridItem | any, b: GridItem | any) => -1 | 0 | 1;
bgFilter?: (item: GridItem | any) => string;
dropOptions?: DropdownOptions;
source?: Array&lt;any&gt; | ((item: GridItem | any) => Array&lt;any&gt; | Promise&lt;Array&lt;GridSourceItem&gt;&gt;);
iconType?: string;
text?: string;
tooltip?: string;
onallchecked?: (this: Grid, col: GridColumnDefinition, flag: boolean) => void;
onchanged?: (this: Grid, item: GridItem | any, value: boolean | any) => void;
}</pre>
</p>
<h3>key</h3>
<code>key?: string</code>
<p>关键字</p>
<h3>type</h3>
<code>type?: keyof GridColumnType | typeof GridColumn</code>
<p>列类型,可以为 <code>Grid.ColumnTypes</code> 枚举值表示内置的通用、输入、下拉、复选框、图标等类型
<pre>declare var ColumnTypes: {
Common: 0,
Input: 1,
Dropdown: 2,
Checkbox: 3,
Icon: 4,
isCheckbox(type: Number): boolean;
}</pre>也可以为符合 <code>GridColumn</code> 接口的类或对象表示自定义类型,接口定义如下
<pre>interface GridColumn {
static create(): HTMLElement;
static createEdit(trigger: (e: any) => void, col: GridColumnDefinition, body: HTMLElement): HTMLElement;
static setValue(element: HTMLElement, val: any): void;
static getValue(e: any): any;
static setStyle(element: HTMLElement, style: { [key: string]: string }): void;
static setEnabled(element: HTMLElement, enabled?: boolean): void;
}</pre>
</p>
<h4>create</h4>
<code>static create(): HTMLElement</code>
<p>创建只读状态的单元格元素</p>
<h4>createEdit</h4>
<code>static createEdit(trigger: (e: any) => void, col: GridColumnDefinition, body: HTMLElement): HTMLElement</code>
<p>创建编辑状态的单元格元素</p>
<samp>trigger: (e: any) => void</samp>
<p>用以触发 Grid 的列修改事件 <code>columnChanged</code> 的函数代理</p>
<samp>col: GridColumnDefinition</samp>
<p>当前列的定义对象</p>
<samp>body: HTMLElement</samp>
<p>Grid 正文表格元素</p>
<h4>setValue</h4>
<code>static setValue(element: HTMLElement, val: any, item: GridItem | any, col: GridColumnDefinition): void</code>
<p>设置单元格值时触发的函数</p>
<samp>element: HTMLElement</samp>
<p>单元格元素</p>
<samp>val: any</samp>
<p>单元格的值</p>
<samp>item: GridItem | any</samp>
<p>单元格所在行的数据项</p>
<samp>col: GridColumnDefinition</samp>
<p>单元格所在列的定义对象</p>
<hr />
<h2>示例</h2>
<pre></pre>
<div id="grid-sample"></div>
<!-- <div style="height: 80px"></div> -->
<script type="text/javascript">
!function () {
const Grid = window["lib-ui"].Grid;
const grid = new Grid(document.querySelector('#grid-sample'));
const statusCol = {
...Grid.GridColumn,
create() {
const container = document.createElement('div');
return container;
},
// createEdit() { },
setValue(element, val) {
element.innerHTML = val;
},
getValue(element) {
return element.innerHTML;
},
setEnabled(element, enabled) {
element.className = enabled === false ? 'disabled' : '';
}
};
const iconCol = {
create() {
const a = document.createElement('a');
a.target = '_blank';
a.className = 'icon-col';
return a;
},
setValue(element, val, _item, col) {
if (col.tooltip) {
element.setAttribute('title', col.tooltip);
}
element.innerText = val;
},
setEnabled(element, enabled) {
element.style.display = enabled === false ? 'none' : '';
},
setStyle: Grid.GridColumn.setStyle
};
// grid.readonly = true;
grid.allowHtml = true;
grid.height = 0;
grid.columns = [
{ key: 'c1', caption: 'column 122222222311111111111111111' },
{ key: 'c2', caption: '选择', allcheck: true, type: Grid.ColumnTypes.Checkbox, enabled: 'enabled' },
{
key: 'c2a',
caption: '下拉',
type: Grid.ColumnTypes.Dropdown,
allowFilter: true,
source: item => {
if (item.source == null) {
return new Promise((resolve, reject) => {
setTimeout(() => {
item.source = [
{ value: 'off', text: 'Off' },
{ value: 'pending', text: 'Pending' },
{ value: 'broken', text: 'Broken' },
{ value: 'running', text: 'Running' }
];
resolve(item.source);
}, 2000);
});
}
return item.source;
},
enabled: 'enabled',
onchanged: (item, value) => console.log('dropdown changed', item, value)
},
{
key: 'c2b',
caption: '自定义',
type: statusCol,
enabled: 'enabled'
},
{ key: 'c2c', caption: '多行编辑', type: Grid.ColumnTypes.Text, enabled: 'enabled' },
{ key: 'c3', caption: 'column 3', width: 90, align: 'right' },
{ key: 'c4', caption: 'Note', type: Grid.ColumnTypes.Input },
{
key: 'c5',
type: Grid.ColumnTypes.Icon,
enabled: 'enabled',
text: 'times',
tooltip: 'Delete',
events: {
onclick() { console.log('deleted', this) }
}
},
{
key: 'c6',
type: iconCol,
enabled: 'enabled',
text: '\uf044',
tooltip: 'Edit',
events: {
onclick() { alert(`Edit, ${this.c1}`) }
}
}
];
grid.columnChanged = (type, index, value) => console.log(`column (${index}), ${type}, ${value}`);
grid.cellClicked = (rId, cId) => console.log(`row (${rId}), column (${cId}) clicked.`);
grid.rowDblClicked = (rId) => console.log(`row (${rId}) double clicked.`);
grid.cellDblClicked = (rId, cId) => console.log(`row (${rId}), column (${cId}) double clicked.`);
grid.init();
grid.source = [
{ c1: 'abc', c2: true, c2a: 'off', c2b: '<font style="color: red; margin-left: 8px">red</font>', c2c: 'multiple lines\nline2\nline3\n\nline5', c3: 12345, c4: 'another note' },
{ c1: 'abc2bbbbaaaaa', c2: false, c2a: 'pending', c2b: '<b style="margin-left: 8px">bold</b>', c3: 1225, c4: 'Note note this is note' },
{ c1: 'type', c2: false, c2a: 'broken', c2c: 'multiple lines\nline2\nline3\n\nline5', c3: 121111 },
{ c1: 'diff', c2: true, c2a: 'running', c3: 124445555555555555 },
{ c1: 'diff', c2: true, c2a: 'running', c3: 12499, enabled: false },
{ c1: 'diff', c2: true, c2a: 'off', c3: 1244445 }
];
window.grid = grid;
}();
</script>
<style type="text/css">
#grid-sample {
height: 500px;
}
#grid-sample>.ui-grid {
height: 100%;
}
</style>
</div>
+6 -5
View File
@@ -51,7 +51,7 @@ const ColumnTypes = {
5: GridTextColumn
};
class Grid {
export class Grid {
#source;
#currentSource;
#parent;
@@ -110,8 +110,6 @@ class Grid {
isCheckbox(type) { return type === 3 }
};
static GridColumn = GridColumn;
constructor(container) {
this.#parent = container;
}
@@ -412,6 +410,11 @@ class Grid {
}
}
clearHeaderCheckbox() {
const boxes = this.#refs.header.querySelectorAll('.ui-check-wrapper>input');
boxes.forEach(box => box.checked = false);
}
#createHeader() {
const thead = createElement('table', 'ui-grid-header');
if (this.headerVisible === false) {
@@ -1553,5 +1556,3 @@ class Grid {
}
}
}
export default Grid;
+22
View File
@@ -1,3 +1,25 @@
/**
* 创建矢量图标元素
* @param type 样式分类,可以是 ['`fa-light`', '`fa-regular`', '`fa-solid`'] 其中之一
* @param id 图标 id
* @param style 样式表对象
*/
export function createIcon(type: string, id: string, style?: { [key: string]: string }): SVGSVGElement
/**
* 修改矢量图标
* @param svg 矢量图标元素
* @param type 样式分类,见 { @link createIcon } 第一个参数
* @param id 图标 id,见 { @link createIcon } 第二个参数
*/
export function changeIcon(svg: SVGSVGElement, type: string, id: string): SVGSVGElement
/**
* 解析容器元素内符合条件的子元素为矢量图标元素
* @param container 容器元素
* @example
* ```
* <svg data-id="user" data-type="fa-solid"></svg>
* ```
* - `data-id`: 见 { @link createIcon } 第二个参数
* - `data-type`: 见 { @link createIcon } 第一个参数
*/
export function resolveIcon(container: HTMLElement): HTMLElement
-50
View File
@@ -1,50 +0,0 @@
<div>
<h1>icon</h1>
<hr />
<p>
创建一个 svg 矢量图标元素,或者解析转换页面上特定类型的 svg
标签到指定的图标元素。
</p>
<h2>createIcon</h2>
<code>function createIcon(type: string, id: string, style?: { [key: string]: string }): SVGElement</code>
<h3>type: string</h3>
<p>
图标类型,可选值目前有 <code>fa-regular</code>、<code>fa-light</code>、<code>fa-solid</code>
</p>
<h3>id: string</h3>
<p>
图形 id,例如
<code>user-edit</code>、<code>address-card</code>、<code>frog</code>……
</p>
<h3>style?: { [key: string]: string }</h3>
<p>
自定义样式的对象
</p>
<h2>resolveIcon</h2>
<code>function resolveIcon(container: HTMLElement): HTMLElement</code>
<h3>container: HTMLElement</h3>
<p>
将把此 HTML 元素下的所有 <code>svg[data-id]</code> 元素解析为图标,<code>[data-id]</code>
同上述 <code>id: string</code>,<code>[data-type]</code> 同上述
<code>type: string</code>
</p>
<hr />
<h2>示例</h2>
<pre>&lt;div id="icon-sample"&gt;
&lt;svg data-id="address-card" data-type="fa-regular"&gt;&lt;/svg&gt;
&lt;svg data-id="user-edit" data-type="fa-light"&gt;&lt;/svg&gt;
&lt;svg data-id="frog" data-type="fa-solid"&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
window["lib-ui"].resolveIcon(document.querySelector("#icon-sample"));
&lt;/script&gt;</pre>
<div id="icon-sample">
<svg data-id="address-card" data-type="fa-regular"></svg>
<svg data-id="user-edit" data-type="fa-light"></svg>
<svg data-id="frog" data-type="fa-solid"></svg>
</div>
<script type="text/javascript">
window["lib-ui"].resolveIcon(document.querySelector("#icon-sample"));
</script>
</div>
+49
View File
@@ -0,0 +1,49 @@
/**
* 创建媒体图片元素
* @param url 图片链接地址
* @returns 返回一个 A 标签元素
*/
export function createPicture(url: string): HTMLAnchorElement
/**
* 创建一个音频播放元素
* @param mime 音频类型,如 `audio/amr`、`audio/ogg`
* @param url 音频 url
*/
export function createAudio(mime: string, url: string): HTMLAudioElement | HTMLDivElement
/**
* 创建一个视频播放元素
* @param url 视频 url
*/
export function createVideo(url: string): HTMLVideoElement
/**
* 创建一个 pdf 文件元素
* @param url pdf 文件 url
*/
export function createPdf(url: string): HTMLDivElement
/**
* 创建一个 smil 文件元素
* @param url smil 文件 url
*/
export function createSmilefile(url: string): HTMLDivElement
/**
* 创建一个 vcard 文件元素
* @param url vcard 文件 url
*/
export function createVcard(url: string): HTMLDivElement
/**
* 创建一个不支持的视频文件元素
* @param url 视频 url
*/
export function createVideofile(url: string): HTMLDivElement
/**
* 创建一个通用文件元素
* @param url 文件 url
*/
export function createFile(url: string): HTMLDivElement
+160
View File
@@ -0,0 +1,160 @@
import "./css/media.scss";
import { createElement } from "../functions";
import { createIcon } from "./icon";
import { get } from "../utility";
export function createPicture(url) {
return createElement('a', a => {
a.className = 'ui-media-picture';
a.target = '_blank';
a.href = url;
},
createElement('img', img => {
img.src = url;
})
);
}
function readBlob(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => {
const data = new Uint8Array(e.target.result);
resolve(data);
};
reader.onerror = reject;
reader.readAsArrayBuffer(blob);
});
}
function playAmrArray(array) {
return new Promise((resolve, reject) => {
const samples = AMR.decode(array);
if (samples != null) {
resolve(samples);
} else {
reject();
}
});
}
function playPcm(samples, ended) {
return new Promise(resolve => {
const ctx = new AudioContext();
ctx.addEventListener('statechange', () => resolve(ctx));
const source = ctx.createBufferSource();
if (typeof ended === 'function') {
source.addEventListener('ended', () => ended(ctx));
}
const buffer = ctx.createBuffer(1, samples.length, 8000);
if (typeof buffer.copyToChannel === 'function') {
buffer.copyToChannel(samples, 0, 0);
} else {
const channelBuffer = buffer.getChannelData(0);
channelBuffer.set(samples);
}
source.buffer = buffer;
source.connect(ctx.destination);
ctx.duration = buffer.duration;
source.start();
// resolve(ctx);
});
}
function getTimeLabel(time) {
time = Math.round(time);
return String(Math.floor(time / 60)).padStart(2, '0') + ':' + String(time % 60).padStart(2, '0');
}
export function createAudio(mime, url) {
if (mime === 'audio/amr' && typeof AMR !== 'undefined') {
const timestamp = createElement('span', 'ui-media-timestamp');
timestamp.textContent = '00:00 / 00:00';
let context;
let timer;
return createElement('div', 'ui-media-audio',
createElement('button', button => {
button.addEventListener('click', () => {
if (context != null) {
clearInterval(timer);
context.close();
context = null;
timestamp.textContent = '00:00 / 00:00';
button.replaceChildren(createIcon('fa-solid', 'play'));
return;
}
get(url, {
accept: mime
})
.then(r => r.blob())
.then(r => readBlob(r))
.then(r => playAmrArray(r))
.then(r => playPcm(r, ctx => {
context = null;
clearInterval(timer);
timestamp.textContent = '00:00 / ' + getTimeLabel(ctx.duration);
button.replaceChildren(createIcon('fa-solid', 'play'));
}))
.then(ctx => {
context = ctx;
button.replaceChildren(createIcon('fa-solid', 'stop'));
const total = getTimeLabel(ctx.duration);
const refresh = () => timestamp.textContent = getTimeLabel(ctx.currentTime) + ' / ' + total;
refresh();
timer = setInterval(refresh, 500);
})
.catch(e => {
clearInterval(timer);
console.error(e);
});
});
},
createIcon('fa-solid', 'play')
),
timestamp
);
}
return createElement('audio', audio => {
audio.src = url;
audio.controls = true;
});
}
export function createVideo(url) {
return createElement('video', video => {
video.className = 'ui-media-video';
video.src = url;
video.controls = true;
});
}
function createFileElement(url, icon) {
return createElement('div', 'ui-media-file',
createIcon('fa-solid', icon),
createElement('a', a => {
a.target = '_blank';
a.href = url;
a.innerText = 'Click here to view the file';
})
);
}
export function createPdf(url) {
return createFileElement(url, 'file-pdf');
}
export function createSmilefile(url) {
return createFileElement(url, 'smile');
}
export function createVcard(url) {
return createFileElement(url, 'id-card');
}
export function createVideofile(url) {
return createFileElement(url, 'photo-video');
}
export function createFile(url) {
return createFileElement(url, 'file-alt');
}
+94
View File
@@ -0,0 +1,94 @@
/**
* 弹出框选项
*/
interface PopupOptions {
/** 弹出框内容,可以是文本或者 html 元素 */
content: string | HTMLElement;
/** 弹出框标题,可以是文本或者 html 元素 */
title: string | HTMLElement;
/** 是否包含遮罩层,默认为 `true` */
mask?: boolean;
/** 遮罩层 z-index */
zIndex?: number;
/** 是否在获取焦点时修改 z-index */
changeZIndex?: boolean;
/** 是否允许移动 */
movable?: boolean;
/** 是否允许修改大小 */
resizable?: boolean;
/** 最小宽度,默认 200 */
minWidth?: number;
/** 最小高度,默认 200 */
minHeight?: number;
/** 是否允许弹出框收折 */
collapsable?: boolean;
/** 弹出框的按钮定义集合 */
buttons?: PopupButton[];
/**
* 遮罩层显示或者隐藏时的回调函数
* @param this 当前 popup 对象
* @param masking 显示或隐藏遮罩层
*/
onMasking?: (this: Popup, masking: boolean) => void;
/**
* 移动结束时的回调函数
* @param this 当前 popup 对象
*/
onMoveEnded?: (this: Popup) => void;
/**
* 修改大小开始时的回调函数
* @param this 当前 popup 对象
*/
onResizeStarted?: (this: Popup) => void;
/**
* 修改大小中的回调函数
* @param this 当前 popup 对象
* @param x 坐标 x
* @param y 坐标 y
* @param width 当前宽度
* @param height 当前高度
*/
onResizing?: (this: Popup, x: number, y: number, width: number, height: number) => void;
/**
* 修改大小结束时的回调函数
* @param this 当前 popup 对象
*/
onResizeEnded?: (this: Popup) => void;
/**
* 弹出框关闭时的回调函数
*/
resolve?: () => void;
}
export class Popup {
constructor(opts?: PopupOptions);
}
interface PopupButton {
tabIndex: number;
key: string;
text: string;
trigger: (this: Popup) => boolean | Promise<boolean>;
}
interface PopupIconTypes {
'info': 'info-circle';
'information': 'info-circle';
'warn': 'exclamation-triangle';
'warning': 'exclamation-triangle';
'question': 'question-circle';
'error': 'times-circle';
}
interface PopupButtonResult {
key: string;
popup: Popup;
}
export function createPopup(title: string | HTMLElement, content: string | HTMLElement, ...buttons: PopupButton[]): Popup
export function showAlert(title: string | HTMLElement, message: string, iconType?: keyof PopupIconTypes, parent?: HTMLElement): Promise<void>
export function showConfirm(title: string | HTMLElement, content: string | HTMLElement, buttons: PopupButton[], iconType?: keyof PopupIconTypes, parent?: HTMLElement): Promise<PopupButtonResult>
-51
View File
@@ -1,51 +0,0 @@
<div>
<h1>popup</h1>
<hr />
<p>
创建弹出窗口。
</p>
<hr />
<h2>示例</h2>
<div id="popup-sample">
<button id="button-popup">Popup</button>
</div>
<script type="text/javascript">
const ui = window['lib-ui'];
document.querySelector('#button-popup').addEventListener('click', () => {
const popup = new ui.Popup({
title: 'title long title, looooooong title, looooooooooooooooooooooooong ~',
content: ui.createElement('div', 'class-content',
ui.createElement('span', span => span.innerText = 'Text content.')
),
mask: false,
// movable: false,
resizable: true,
collapsable: true,
minWidth: 210,
minHeight: 200,
buttons: [
{
text: 'Loading', trigger: p => {
p.loading = true;
setTimeout(() => p.loading = false, 1000);
return false;
}
},
{ text: 'OK' }
],
onMoveEnded: () => console.log('move ended.', popup.rect),
onResizeEnded: () => console.log('resize ended.', popup.rect)
});
popup.show();
window.popup = popup;
});
</script>
<style type="text/css">
.ui-popup-mask .ui-popup-container {
min-width: 210px;
min-height: 200px;
max-width: unset;
}
</style>
</div>
+7 -4
View File
@@ -38,7 +38,7 @@ function trimPx(px) {
return px;
}
class Popup {
export class Popup {
#mask;
#option;
#bounds;
@@ -116,6 +116,9 @@ class Popup {
if (typeof this.#option.onMasking === 'function') {
this.#option.onMasking.call(this, false);
}
if (typeof this.#option.resolve === 'function') {
this.#option.resolve();
}
}
create() {
@@ -124,7 +127,7 @@ class Popup {
if (option.mask === false) {
mask.classList.add('ui-popup-transparent');
} else if (typeof option.onMasking === 'function') {
this.#option.onMasking.call(this, true);
option.onMasking.call(this, true);
}
if (!isNaN(option.zIndex)) {
mask.style.zIndex = String(option.zIndex);
@@ -478,8 +481,6 @@ class Popup {
}
}
export default Popup;
export function createPopup(title, content, ...buttons) {
const popup = new Popup({
title,
@@ -506,6 +507,7 @@ export function showAlert(title, message, iconType = 'info', parent = document.b
createIcon('fa-solid', iconTypes[iconType] ?? 'info-circle'),
createElement('span', span => span.innerText = message)
),
resolve,
buttons: [
{ text: r('ok', 'OK'), trigger: resolve }
]
@@ -529,6 +531,7 @@ export function showConfirm(title, content, buttons, iconType = 'question', pare
const popup = new Popup({
title,
content: wrapper,
resolve,
buttons: buttons?.map(b => {
return {
text: b.text,
+16
View File
@@ -1,2 +1,18 @@
/**
* 为元素设置一个 tooltip
* @param container 要设置 tooltip 的容器元素
* @param content 提示内容,可以是字符串也可以是 html 元素
* @param flag 是否仅在元素内容没有呈现完全时显示 tooltip
* @param parent 呈现在哪个父元素上,默认添加在 `container` 末端
*/
export function setTooltip(container: HTMLElement, content: string | HTMLElement, flag?: boolean, parent?: HTMLElement): HTMLElement
/**
* 解析容器元素内符合条件的子元素,为其添加 tooltip
* @param container 容器元素
* @example
* ```
* <span title="tooltip text"></span>
* ```
*/
export function resolveTooltip(container?: HTMLElement): HTMLElement
-54
View File
@@ -1,54 +0,0 @@
<div>
<h1>tooltip</h1>
<hr />
<p>
给某个元素或者页面上含有 title 属性的元素设置一个统一样式的 tooltip。
</p>
<h2>setTooltip</h2>
<code>function setTooltip(container: HTMLElement, content: string | HTMLElement, flag?: boolean, parent?: HTMLElement): void</code>
<h3>container: HTMLElement</h3>
<p>
要设置 tooltip 的元素
</p>
<h3>content: string | HTMLElement</h3>
<p>
要设置的 tooltip 内容,允许为字符串或者 HTML 元素
</p>
<h3>flag?: boolean</h3>
<p>
是否启用严格模式,只有显示不完整时才显示 tooltip
</p>
<h3>parent?: HTMLElement</h3>
<p>
创建在哪个元素内,默认创建在目标元素之内
</p>
<h2>resolveTooltip</h2>
<code>function resolveTooltip(container?: HTMLElement): HTMLElement</code>
<h3>container?: HTMLElement</h3>
<p>
给此元素,为 null 则把 document.body 下的所有含有 title 属性的子元素设置成统一样式的 tooltip
</p>
<hr />
<h2>示例</h2>
<pre>&lt;div id="tooltip-sample"&gt;
&lt;!-- 1 --&gt;
&lt;blockquote title="From MDN Website"&gt;To send an HTTP request, create an XMLHttpRequest object, open a URL, and
send the request. After the transaction completes, the object will contain useful information such as the
response body and the HTTP status of the result.&lt;/blockquote&gt;
&lt;!-- 2 --&gt;
&lt;button title="Test to send request through XMLHttpRequest."&gt;Test&lt;/button&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
window["lib-ui"].resolveCheckbox(document.querySelector("#checkbox-sample"));
&lt;/script&gt;</pre>
<div id="tooltip-sample">
<blockquote title="From MDN Website">To send an HTTP request, create an XMLHttpRequest object, open a URL, and
send the request. After the transaction completes, the object will contain useful information such as the
response body and the HTTP status of the result.</blockquote>
<button title="Test to send request through XMLHttpRequest.">Test</button>
</div>
<script type="text/javascript">
window["lib-ui"].resolveTooltip(document.querySelector("#tooltip-sample"));
</script>
</div>
+68 -60
View File
@@ -2,7 +2,7 @@ import './css/tooltip.scss';
import { createElement } from "../functions";
// import { global } from "../utility";
function setTooltip(container, content, flag = false, parent = null) {
export function setTooltip(container, content, flag = false, parent = null) {
const isParent = parent instanceof HTMLElement;
if (isParent) {
const tipid = container.dataset.tipId;
@@ -73,64 +73,77 @@ function setTooltip(container, content, flag = false, parent = null) {
top -= p.scrollTop;
p = p.parentElement;
}
// check overflow
let t = c.offsetTop;
let l = c.offsetLeft;
p = c.offsetParent;
let lastWidth = p.clientWidth;
let lastHeight = p.clientHeight;
while (p != null) {
const overflow = window.getComputedStyle(p).overflow;
if (overflow !== 'visible') {
t -= p.scrollTop;
l -= p.scrollLeft;
break;
}
t += p.offsetTop;
l += p.offsetLeft;
const w = p.clientWidth;
if (w < lastWidth) {
lastWidth += l;
} else {
lastWidth = p.clientWidth;
}
const h = p.clientHeight;
if (h < lastHeight) {
lastHeight += t;
} else {
lastHeight = p.clientHeight;
}
const parent = p.offsetParent;
while (p != null && p != parent) {
t -= p.scrollTop;
l -= p.scrollLeft;
p = p.parentElement;
}
}
wrapper.style.display = '';
const offsetHeight = wrapper.offsetHeight;
if (t - offsetHeight - 14 < 0) {
const parentOffsetHeight = c.parentElement.offsetHeight;
if (t + parentOffsetHeight + offsetHeight + 10 > lastHeight) {
top = t + (parentOffsetHeight - offsetHeight) / 2;
if (top + offsetHeight + 1 > lastHeight) {
top = lastHeight - offsetHeight - 1;
}
wrapper.classList.add('ui-tooltip-no');
} else {
top += parentOffsetHeight + 10;
const offsetWidth = wrapper.offsetWidth;
if (isParent) {
top -= offsetHeight + 14;
if (top < -offsetHeight) {
top += c.offsetHeight + offsetHeight + 14;
wrapper.classList.add('ui-tooltip-down');
}
left += (c.offsetWidth - offsetWidth) / 2;
if (left < 1) {
left = 1;
}
} else {
top -= offsetHeight + 14;
wrapper.classList.remove('ui-tooltip-down');
}
const offsetWidth = wrapper.offsetWidth;
left += (c.offsetWidth - offsetWidth) / 2;
if (l - offsetWidth < 0) {
left = 1;
} else if (left + offsetWidth + 1 > lastWidth) {
left = lastWidth - offsetWidth - 1;
// check overflow
let t = c.offsetTop;
let l = c.offsetLeft;
p = c.offsetParent;
let lastWidth = p.clientWidth;
let lastHeight = p.clientHeight;
while (p != null) {
const overflow = window.getComputedStyle(p).overflow;
if (overflow !== 'visible') {
break;
}
t += p.offsetTop;
l += p.offsetLeft;
const parent = p.offsetParent;
while (p != null) {
const w = p.clientWidth;
if (w < lastWidth) {
lastWidth += l;
} else {
lastWidth = p.clientWidth;
}
const h = p.clientHeight;
if (h < lastHeight) {
lastHeight += t;
} else {
lastHeight = p.clientHeight;
}
t -= p.scrollTop;
l -= p.scrollLeft;
if (p === parent) {
break;
}
p = p.parentElement;
}
}
if (t - offsetHeight - 14 < 0) {
const containerOffsetHeight = c.offsetHeight;
if (t + containerOffsetHeight + offsetHeight + 14 > lastHeight) {
top = t + (containerOffsetHeight - offsetHeight) / 2;
if (top + offsetHeight + 1 > lastHeight) {
top = lastHeight - offsetHeight - 1;
}
wrapper.classList.add('ui-tooltip-no');
} else {
top += containerOffsetHeight + 14;
wrapper.classList.add('ui-tooltip-down');
}
} else {
top -= offsetHeight + 14;
wrapper.classList.remove('ui-tooltip-down');
}
left += (c.offsetWidth - offsetWidth) / 2;
if (l - offsetWidth < 0) {
left = 1;
} else if (left + offsetWidth + 1 > lastWidth) {
left = lastWidth - offsetWidth - 1;
}
}
// wrapper.style.left = `${left}px`;
// wrapper.style.top = `${top}px`;
@@ -151,7 +164,7 @@ function setTooltip(container, content, flag = false, parent = null) {
return container;
}
function resolveTooltip(container = document.body) {
export function resolveTooltip(container = document.body) {
const tips = container.querySelectorAll('[title]');
for (let tip of tips) {
const title = tip.getAttribute('title');
@@ -162,8 +175,3 @@ function resolveTooltip(container = document.body) {
}
return container;
}
export {
setTooltip,
resolveTooltip
}
-40
View File
@@ -1,40 +0,0 @@
<div>
<h1>cookie</h1>
<hr />
<p>
cookie 操作工具类:获取、设置、删除。
</p>
<h2>getCookie</h2>
<code>function getCookie(name: string): string</code>
<h3>name: string</h3>
<p>
待获取的 cookie 关键字
</p>
<h2>setCookie</h2>
<code>function setCookie(name: string, value: string, expireDays?: Number): void</code>
<h3>name: string</h3>
<p>
待设置的 cookie 关键字
</p>
<h3>value: string</h3>
<p>
待设置的值
</p>
<h3>expireDays?: Number</h3>
<p>
有效期天数
</p>
<h2>deleteCookie</h2>
<code>function deleteCookie(name: string): void</code>
<h3>name: string</h3>
<p>
待删除的 cookie 关键字
</p>
<hr />
<h2>用法</h2>
<pre>const cookie = window["lib-utility"];
cookie.getCookie('user_id');
cookie.setCookie('user_id', 'guest');
cookie.deleteCookie('user_id');</pre>
</div>
-74
View File
@@ -1,74 +0,0 @@
<div>
<h1>lgres</h1>
<hr />
<p>
语言资源工具类,用以设置页面以及脚本中的多语言。
</p>
<h2>r</h2>
<code>function r(key: string, defaultValue?: any): any</code>
<h3>key: string</h3>
<p>
语言资源的关键字
</p>
<h3>defaultValue?: any</h3>
<p>
资源的默认值,如无法获取该语言资源,则返回该值
</p>
<h2>lang</h2>
<code>const lang : {}</code>
<h3>get current(): string</h3>
<p>
返回当前语言 id
</p>
<h3>get unknownError(): string</h3>
<p>
未知错误的语言资源,默认为 <code>'An unknown error occurred, please contact the administrator.'</code>
</p>
<h3>get savedSuccessfully(): string</h3>
<p>
保存成功的语言资源,默认为 <code>'Saved successfully.'</code>
</p>
<h2>init</h2>
<code>function init(dom?: HTMLElement, options?: LgresOptions): Promise&lt;LanguageResource&gt;</code>
<h3>dom?: HTMLElement</h3>
<p>
待处理的元素,为空时处理整个页面
</p>
<h3>options?: LgresOptions</h3>
<p>
初始化参数,结构为
<pre>interface LgresOptions {
template?: string,
callback?: (result: any) => void
}</pre>
</p>
<h4>template?: string</h4>
<p>
语言资源文件的后缀,资源文件 url 为 <code>`language/${lgid}${template}`</code>
</p>
<h4>callback?: (result: any) => void</h4>
<p>
资源初始化后的回调函数,可能在 DOM 加载完成之前触发。
</p>
<h3>return: Promise&lt;LanguageResource&gt;</h3>
<p>
返回一个包含资源结果的 Promise,将在 DOM 加载完成之后触发。
</p>
<p><code>LanguageResource</code> 结构为
<pre>interface LanguageResource {
r(key: string, defaultValue?: any): any
}</pre>
</p>
<hr />
<h2>用法</h2>
<pre>const lgres = window["lib-utility"];
lgres.init(document.body, {
template: '/res.json',
callback: res => document.title = res.r('title', 'Default Title')
}).then(res => {
document.querySelector('#header').innerText = res.r('header', 'My Header');
const msg = lgres.lang.unknownError;
document.querySelector('#message').innerText = lgres.lang.unknownError;
});</pre>
</div>
+2 -1
View File
@@ -2,7 +2,8 @@ interface RequestOptions {
method?: string;
accept?: string;
contentType?: string;
customerHeaders?: { [key: string]: string };
customHeaders?: { [key: string]: string };
mode?: RequestMode | undefined;
signal?: AbortSignal | null;
progress?: (this: XMLHttpRequestUpload, ev: ProgressEvent<XMLHttpRequestEventTarget>) => any
}
-111
View File
@@ -1,111 +0,0 @@
<div>
<h1>request</h1>
<hr />
<p>
网络请求工具类,可以实现比较常见的一些请求操作。
</p>
<h2>get</h2>
<code>function get(url: string, options?: RequestOptions): Promise&lt;Response&gt;</code>
<h3>url: string</h3>
<p>
url 地址
</p>
<h3>options?: RequestOptions</h3>
<p>
请求的配置参数,结构为
<pre>interface RequestOptions {
method?: string;
accept?: string;
contentType?: string;
customerHeaders?: { [key: string]: string };
signal?: AbortSignal | null;
progress?: (this: XMLHttpRequestUpload, ev: ProgressEvent&lt;XMLHttpRequestEventTarget&gt;) => any
}</pre>
</p>
<h4>method?: string</h4>
<p>
请求类型,默认为 GET 或 POST
</p>
<h4>accept?: string</h4>
<p>
Accept 请求头的值
</p>
<h4>contentType?: string</h4>
<p>
Content-Type 请求头的值
</p>
<h4>customerHeaders?: { [key: string]: string }</h4>
<p>
自定义请求头,例如
<pre>{
'X-Auth-Id': 'xxxxxx',
'X-Auth-Token': 'xxxxxx'
}</pre>
</p>
<h4>signal?: AbortSignal | null</h4>
<p>
终止器的信号,用来控制终止请求任务
</p>
<h4>progress?: (this: XMLHttpRequestUpload, ev: ProgressEvent&lt;XMLHttpRequestEventTarget&gt;) => any</h4>
<p>
调用 upload 方法时在上传过程中触发的事件,返回进度参数
</p>
<h3>return: Promise&lt;Response&gt;</h3>
<p>
返回一个结果为 Response 对象的 Promise
</p>
<h2>post</h2>
<code>function post(url: string, data?: BodyInit | null, options?: RequestOptions): Promise&lt;Response&gt;</code>
<h3>url: string</h3>
<p>
url 地址
</p>
<h3>data?: BodyInit | null</h3>
<p>
post 请求传递的请求正文,可以是 FormData 或者任意对象,后者会经 JSON 序列化后发送
</p>
<h3>options?: RequestOptions</h3>
<p>
请求的配置参数,结构如上述 get
</p>
<h3>return: Promise&lt;Response&gt;</h3>
<p>
返回一个结果为 Response 对象的 Promise
</p>
<h2>upload</h2>
<code>upload(url: string, data: FormData, options?: RequestOptions): Promise&lt;XMLHttpRequest&gt;</code>
<h3>url: string</h3>
<p>
url 地址
</p>
<h3>data: FormData</h3>
<p>
upload 请求传递的请求正文,仅支持 FormData
</p>
<h3>options?: RequestOptions</h3>
<p>
请求的配置参数,结构如上述 get,仅使用其中 <code>progress</code> 与 <code>customerHeaders</code>
</p>
<h3>return: Promise&lt;XMLHttpRequest&gt;</h3>
<p>
返回一个结果为 XMLHttpRequest 对象的 Promise
</p>
<hr />
<h2>用法</h2>
<pre>const request = window["lib-utility"];
request.get('https://www.baidu.com')
.then(r => r.text())
.then(text => console.log(text));
request.post('api/query', { id: 101 })
.then(r => r.json())
.then(result => console.log(result.data));
request.upload('api/upload', data, {
progress: ev => {
console.log(`loaded: ${ev.loaded}, total: ${ev.total}`);
}
})
.then(() => console.log('done.'));</pre>
</div>
+10 -9
View File
@@ -12,9 +12,10 @@ function get(url, options = {}) {
return fetch(combineUrl(url), {
method: options.method || 'GET',
headers: {
...options.customerHeaders,
'Accept': options.accept || 'application/json'
...options.customHeaders,
'Accept': options.accept ?? 'application/json'
},
mode: options.mode,
signal: options.signal,
cache: 'default'
});
@@ -29,16 +30,16 @@ function post(url, data, options = {}) {
data = JSON.stringify(data);
}
// contentType = 'application/json';
if (options.customerHeaders == null) {
options.customerHeaders = {};
if (options.customHeaders == null) {
options.customHeaders = {};
}
if (options.customerHeaders['Content-Type'] == null) {
options.customerHeaders['Content-Type'] = 'application/json';
if (options.customHeaders['Content-Type'] == null) {
options.customHeaders['Content-Type'] = 'application/json';
}
}
return fetch(combineUrl(url), {
method: options.method || 'POST',
headers: options.customerHeaders,
headers: options.customHeaders,
body: data,
signal: options.signal,
cache: 'no-cache'
@@ -65,8 +66,8 @@ function upload(url, data, options = {}) {
}, false);
}
request.open('POST', combineUrl(url));
if (options.customerHeaders != null) {
for (let header of Object.entries(options.customerHeaders)) {
if (options.customHeaders != null) {
for (let header of Object.entries(options.customHeaders)) {
request.setRequestHeader(header[0], header[1]);
}
}
-73
View File
@@ -1,73 +0,0 @@
<div>
<h1>strings</h1>
<hr />
<p>
字符串操作工具类。
</p>
<h2>nullOrEmpty</h2>
<code>function nullOrEmpty(s?: string | any | null): boolean</code>
<h3>s?: string | any | null</h3>
<p>
待判断的对象,非字符串或者长度为 0 则返回 true
</p>
<h2>contains</h2>
<code>function contains(s: string, key: string | any, ignoreCase?: boolean): boolean</code>
<h3>s: string</h3>
<p>
待判断的字符串
</p>
<h3>key: string | any</h3>
<p>
检查字符串中是否含有该值,非字符串会先转换为字符串后再进行判断
</p>
<h3>ignoreCase?: boolean</h3>
<p>
判断时是否忽略大小写
</p>
<h2>endsWith</h2>
<code>function endsWith(s: string, suffix: string): boolean</code>
<h3>s: string</h3>
<p>
待判断的字符串
</p>
<h3>suffix: string</h3>
<p>
检查字符串是否以该字符串结尾
</p>
<h2>padStart</h2>
<code>function padStart(s: string, num: Number, char: string): boolean</code>
<h3>s: string</h3>
<p>
基础字符串
</p>
<h3>num: Number</h3>
<p>
对齐字符个数
</p>
<h3>char: string</h3>
<p>
用此字符串填充,使得字符串对齐,默认为 ' '
</p>
<h2>formatUrl</h2>
<code>function formatUrl(msg: string): string</code>
<h3>msg: string</h3>
<p>
把超链接解析替换为图标
</p>
<h2>escapeHtml</h2>
<code>function escapeHtml(text: string): string</code>
<h3>text: string</h3>
<p>
解析转换 html 代码为显示内容
</p>
<hr />
<h2>用法</h2>
<pre>const util = window["lib-utility"];
let s = 'test string';
console.log(util.nullOrEmpty(s)); // false
console.log(util.contains(s, 'abc')); // true
console.log(util.endsWith(s, 'string')); // true
s = util.padStart(s, 16, '0');
// '00000test string'</pre>
</div>
+9 -29
View File
@@ -1,6 +1,7 @@
import './style.scss'
// import javascriptLogo from './javascript.svg'
import { get } from './lib/utility'
import { createPicture, createAudio, createVideo, createPdf } from './lib/ui/media'
// document.querySelector('#js-logo').src = javascriptLogo
@@ -9,34 +10,13 @@ window.consts = {
resver: 20230329
}
function navigate(page) {
get(page, {
accept: 'text/html'
})
.then(r => r.text())
.then(html => {
const range = document.createRange();
range.selectNode(document.body);
const doc = range.createContextualFragment(html);
const container = document.querySelector('#container');
container.replaceChildren(doc);
container.scrollTop = 0;
});
}
document.querySelector('#directory').addEventListener('click', ev => {
const page = ev.target.dataset.page;
if (typeof page === 'string') {
location.hash = page;
navigate(page);
}
});
let page = location.hash;
if (page.length > 1) {
page = page.substring(1);
navigate(page);
}
document.querySelector('#container').replaceChildren(
// createPicture('https://fleet.foresightintelligence.com/doc/mmspart/1740581frZuuFhz5WWCysxs9oGB.jpg'),
createAudio('audio/amr', 'http://vite.tsanie.org/1055003tb0DisaMu1615PeSXKG.amr'),
createPdf('AG-PRO COMPANIES', 'https://fleet.foresightintelligence.com/doc/mmspart/1333321JLrYhkGYqsw6QSVMx3d.pdf'),
// createPicture('https://fleet.foresightintelligence.com/doc/mmspart/138390UGZUMWRmqBsEgPnWuW16.gif'),
// createVideo('https://fleet.foresightintelligence.com/doc/mmspart/17359338sR5qsG7TvS7eaUdP9PL.mp4'),
);
/*
init(null, {
@@ -56,7 +36,7 @@ init(null, {
document.querySelector('#button-fetch').addEventListener('click', () => {
get('javascript.svg', {
// contentType: '',
customerHeaders: {
customHeaders: {
'X-Auth': 'test/authentication'
}
})
+230 -103
View File
@@ -10,6 +10,7 @@
"devDependencies": {
"postcss-preset-env": "^8.2.0",
"sass": "^1.60.0",
"typedoc": "^0.24.8",
"vite": "^4.0.4",
"vite-plugin-externals": "^0.6.2"
}
@@ -590,9 +591,9 @@
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz",
"integrity": "sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.12.tgz",
"integrity": "sha512-LIxaNIQfkFZbTLb4+cX7dozHlAbAshhFE5PKdro0l+FnCpx1GDJaQ2WMcqm+ToXKMt8p8Uojk/MFRuGyz3V5Sw==",
"cpu": [
"arm"
],
@@ -606,9 +607,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz",
"integrity": "sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.12.tgz",
"integrity": "sha512-BMAlczRqC/LUt2P97E4apTBbkvS9JTJnp2DKFbCwpZ8vBvXVbNdqmvzW/OsdtI/+mGr+apkkpqGM8WecLkPgrA==",
"cpu": [
"arm64"
],
@@ -622,9 +623,9 @@
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.18.tgz",
"integrity": "sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.12.tgz",
"integrity": "sha512-zU5MyluNsykf5cOJ0LZZZjgAHbhPJ1cWfdH1ZXVMXxVMhEV0VZiZXQdwBBVvmvbF28EizeK7obG9fs+fpmS0eQ==",
"cpu": [
"x64"
],
@@ -638,9 +639,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz",
"integrity": "sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.12.tgz",
"integrity": "sha512-zUZMep7YONnp6954QOOwEBwFX9svlKd3ov6PkxKd53LGTHsp/gy7vHaPGhhjBmEpqXEXShi6dddjIkmd+NgMsA==",
"cpu": [
"arm64"
],
@@ -654,9 +655,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz",
"integrity": "sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.12.tgz",
"integrity": "sha512-ohqLPc7i67yunArPj1+/FeeJ7AgwAjHqKZ512ADk3WsE3FHU9l+m5aa7NdxXr0HmN1bjDlUslBjWNbFlD9y12Q==",
"cpu": [
"x64"
],
@@ -670,9 +671,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz",
"integrity": "sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.12.tgz",
"integrity": "sha512-GIIHtQXqgeOOqdG16a/A9N28GpkvjJnjYMhOnXVbn3EDJcoItdR58v/pGN31CHjyXDc8uCcRnFWmqaJt24AYJg==",
"cpu": [
"arm64"
],
@@ -686,9 +687,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz",
"integrity": "sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.12.tgz",
"integrity": "sha512-zK0b9a1/0wZY+6FdOS3BpZcPc1kcx2G5yxxfEJtEUzVxI6n/FrC2Phsxj/YblPuBchhBZ/1wwn7AyEBUyNSa6g==",
"cpu": [
"x64"
],
@@ -702,9 +703,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz",
"integrity": "sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.12.tgz",
"integrity": "sha512-y75OijvrBE/1XRrXq1jtrJfG26eHeMoqLJ2dwQNwviwTuTtHGCojsDO6BJNF8gU+3jTn1KzJEMETytwsFSvc+Q==",
"cpu": [
"arm"
],
@@ -718,9 +719,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz",
"integrity": "sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.12.tgz",
"integrity": "sha512-JKgG8Q/LL/9sw/iHHxQyVMoQYu3rU3+a5Z87DxC+wAu3engz+EmctIrV+FGOgI6gWG1z1+5nDDbXiRMGQZXqiw==",
"cpu": [
"arm64"
],
@@ -734,9 +735,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz",
"integrity": "sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.12.tgz",
"integrity": "sha512-yoRIAqc0B4lDIAAEFEIu9ttTRFV84iuAl0KNCN6MhKLxNPfzwCBvEMgwco2f71GxmpBcTtn7KdErueZaM2rEvw==",
"cpu": [
"ia32"
],
@@ -750,9 +751,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz",
"integrity": "sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.12.tgz",
"integrity": "sha512-qYgt3dHPVvf/MgbIBpJ4Sup/yb9DAopZ3a2JgMpNKIHUpOdnJ2eHBo/aQdnd8dJ21X/+sS58wxHtA9lEazYtXQ==",
"cpu": [
"loong64"
],
@@ -766,9 +767,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz",
"integrity": "sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.12.tgz",
"integrity": "sha512-wHphlMLK4ufNOONqukELfVIbnGQJrHJ/mxZMMrP2jYrPgCRZhOtf0kC4yAXBwnfmULimV1qt5UJJOw4Kh13Yfg==",
"cpu": [
"mips64el"
],
@@ -782,9 +783,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz",
"integrity": "sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.12.tgz",
"integrity": "sha512-TeN//1Ft20ZZW41+zDSdOI/Os1bEq5dbvBvYkberB7PHABbRcsteeoNVZFlI0YLpGdlBqohEpjrn06kv8heCJg==",
"cpu": [
"ppc64"
],
@@ -798,9 +799,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz",
"integrity": "sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.12.tgz",
"integrity": "sha512-AgUebVS4DoAblBgiB2ACQ/8l4eGE5aWBb8ZXtkXHiET9mbj7GuWt3OnsIW/zX+XHJt2RYJZctbQ2S/mDjbp0UA==",
"cpu": [
"riscv64"
],
@@ -814,9 +815,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz",
"integrity": "sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.12.tgz",
"integrity": "sha512-dJ3Rb3Ei2u/ysSXd6pzleGtfDdc2MuzKt8qc6ls8vreP1G3B7HInX3i7gXS4BGeVd24pp0yqyS7bJ5NHaI9ing==",
"cpu": [
"s390x"
],
@@ -830,9 +831,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz",
"integrity": "sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.12.tgz",
"integrity": "sha512-OrNJMGQbPaVyHHcDF8ybNSwu7TDOfX8NGpXCbetwOSP6txOJiWlgQnRymfC9ocR1S0Y5PW0Wb1mV6pUddqmvmQ==",
"cpu": [
"x64"
],
@@ -846,9 +847,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz",
"integrity": "sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.12.tgz",
"integrity": "sha512-55FzVCAiwE9FK8wWeCRuvjazNRJ1QqLCYGZVB6E8RuQuTeStSwotpSW4xoRGwp3a1wUsaVCdYcj5LGCASVJmMg==",
"cpu": [
"x64"
],
@@ -862,9 +863,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz",
"integrity": "sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.12.tgz",
"integrity": "sha512-qnluf8rfb6Y5Lw2tirfK2quZOBbVqmwxut7GPCIJsM8lc4AEUj9L8y0YPdLaPK0TECt4IdyBdBD/KRFKorlK3g==",
"cpu": [
"x64"
],
@@ -878,9 +879,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz",
"integrity": "sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.12.tgz",
"integrity": "sha512-+RkKpVQR7bICjTOPUpkTBTaJ4TFqQBX5Ywyd/HSdDkQGn65VPkTsR/pL4AMvuMWy+wnXgIl4EY6q4mVpJal8Kg==",
"cpu": [
"x64"
],
@@ -894,9 +895,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz",
"integrity": "sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.12.tgz",
"integrity": "sha512-GNHuciv0mFM7ouzsU0+AwY+7eV4Mgo5WnbhfDCQGtpvOtD1vbOiRjPYG6dhmMoFyBjj+pNqQu2X+7DKn0KQ/Gw==",
"cpu": [
"arm64"
],
@@ -910,9 +911,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz",
"integrity": "sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.12.tgz",
"integrity": "sha512-kR8cezhYipbbypGkaqCTWIeu4zID17gamC8YTPXYtcN3E5BhhtTnwKBn9I0PJur/T6UVwIEGYzkffNL0lFvxEw==",
"cpu": [
"ia32"
],
@@ -926,9 +927,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz",
"integrity": "sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.12.tgz",
"integrity": "sha512-O0UYQVkvfM/jO8a4OwoV0mAKSJw+mjWTAd1MJd/1FCX6uiMdLmMRPK/w6e9OQ0ob2WGxzIm9va/KG0Ja4zIOgg==",
"cpu": [
"x64"
],
@@ -953,6 +954,12 @@
"node": ">=0.4.0"
}
},
"node_modules/ansi-sequence-parser": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz",
"integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==",
"dev": true
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
@@ -999,6 +1006,12 @@
"postcss": "^8.1.0"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -1008,6 +1021,15 @@
"node": ">=8"
}
},
"node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
@@ -1186,9 +1208,9 @@
"dev": true
},
"node_modules/esbuild": {
"version": "0.17.18",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz",
"integrity": "sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==",
"version": "0.18.12",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.12.tgz",
"integrity": "sha512-XuOVLDdtsDslXStStduT41op21Ytmf4/BDS46aa3xPJ7X5h2eMWBF1oAe3QjUH3bDksocNXgzGUZ7XHIBya6Tg==",
"dev": true,
"hasInstallScript": true,
"bin": {
@@ -1198,28 +1220,28 @@
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/android-arm": "0.17.18",
"@esbuild/android-arm64": "0.17.18",
"@esbuild/android-x64": "0.17.18",
"@esbuild/darwin-arm64": "0.17.18",
"@esbuild/darwin-x64": "0.17.18",
"@esbuild/freebsd-arm64": "0.17.18",
"@esbuild/freebsd-x64": "0.17.18",
"@esbuild/linux-arm": "0.17.18",
"@esbuild/linux-arm64": "0.17.18",
"@esbuild/linux-ia32": "0.17.18",
"@esbuild/linux-loong64": "0.17.18",
"@esbuild/linux-mips64el": "0.17.18",
"@esbuild/linux-ppc64": "0.17.18",
"@esbuild/linux-riscv64": "0.17.18",
"@esbuild/linux-s390x": "0.17.18",
"@esbuild/linux-x64": "0.17.18",
"@esbuild/netbsd-x64": "0.17.18",
"@esbuild/openbsd-x64": "0.17.18",
"@esbuild/sunos-x64": "0.17.18",
"@esbuild/win32-arm64": "0.17.18",
"@esbuild/win32-ia32": "0.17.18",
"@esbuild/win32-x64": "0.17.18"
"@esbuild/android-arm": "0.18.12",
"@esbuild/android-arm64": "0.18.12",
"@esbuild/android-x64": "0.18.12",
"@esbuild/darwin-arm64": "0.18.12",
"@esbuild/darwin-x64": "0.18.12",
"@esbuild/freebsd-arm64": "0.18.12",
"@esbuild/freebsd-x64": "0.18.12",
"@esbuild/linux-arm": "0.18.12",
"@esbuild/linux-arm64": "0.18.12",
"@esbuild/linux-ia32": "0.18.12",
"@esbuild/linux-loong64": "0.18.12",
"@esbuild/linux-mips64el": "0.18.12",
"@esbuild/linux-ppc64": "0.18.12",
"@esbuild/linux-riscv64": "0.18.12",
"@esbuild/linux-s390x": "0.18.12",
"@esbuild/linux-x64": "0.18.12",
"@esbuild/netbsd-x64": "0.18.12",
"@esbuild/openbsd-x64": "0.18.12",
"@esbuild/sunos-x64": "0.18.12",
"@esbuild/win32-arm64": "0.18.12",
"@esbuild/win32-ia32": "0.18.12",
"@esbuild/win32-x64": "0.18.12"
}
},
"node_modules/escalade": {
@@ -1350,6 +1372,12 @@
"node": ">=0.12.0"
}
},
"node_modules/jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
"dev": true
},
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@@ -1362,6 +1390,12 @@
"graceful-fs": "^4.1.6"
}
},
"node_modules/lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
"dev": true
},
"node_modules/magic-string": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
@@ -1371,6 +1405,33 @@
"sourcemap-codec": "^1.4.8"
}
},
"node_modules/marked": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
"integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
"dev": true,
"bin": {
"marked": "bin/marked.js"
},
"engines": {
"node": ">= 12"
}
},
"node_modules/minimatch": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
@@ -1432,9 +1493,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.23",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
"integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
"version": "8.4.26",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz",
"integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==",
"dev": true,
"funding": [
{
@@ -2034,9 +2095,9 @@
}
},
"node_modules/rollup": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.0.tgz",
"integrity": "sha512-ANPhVcyeHvYdQMUyCbczy33nbLzI7RzrBje4uvNiTDJGIMtlKoOStmympwr9OtS1LZxiDmE2wvxHyVhoLtf1KQ==",
"version": "3.26.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.2.tgz",
"integrity": "sha512-6umBIGVz93er97pMgQO08LuH3m6PUb3jlDUUGFsNJB6VgTCUaDFpupf5JfU30529m/UKOgmiX+uY6Sx8cOYpLA==",
"dev": true,
"bin": {
"rollup": "dist/bin/rollup"
@@ -2066,6 +2127,18 @@
"node": ">=14.0.0"
}
},
"node_modules/shiki": {
"version": "0.14.3",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz",
"integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==",
"dev": true,
"dependencies": {
"ansi-sequence-parser": "^1.1.0",
"jsonc-parser": "^3.2.0",
"vscode-oniguruma": "^1.7.0",
"vscode-textmate": "^8.0.0"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
@@ -2094,6 +2167,41 @@
"node": ">=8.0"
}
},
"node_modules/typedoc": {
"version": "0.24.8",
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.8.tgz",
"integrity": "sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==",
"dev": true,
"dependencies": {
"lunr": "^2.3.9",
"marked": "^4.3.0",
"minimatch": "^9.0.0",
"shiki": "^0.14.1"
},
"bin": {
"typedoc": "bin/typedoc"
},
"engines": {
"node": ">= 14.14"
},
"peerDependencies": {
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x"
}
},
"node_modules/typescript": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
"integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
"dev": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
@@ -2140,14 +2248,14 @@
"dev": true
},
"node_modules/vite": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.3.3.tgz",
"integrity": "sha512-MwFlLBO4udZXd+VBcezo3u8mC77YQk+ik+fbc0GZWGgzfbPP+8Kf0fldhARqvSYmtIWoAJ5BXPClUbMTlqFxrA==",
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.4.3.tgz",
"integrity": "sha512-IMnXQXXWgLi5brBQx/4WzDxdzW0X3pjO4nqFJAuNvwKtxzAmPzFE1wszW3VDpAGQJm3RZkm/brzRdyGsnwgJIA==",
"dev": true,
"dependencies": {
"esbuild": "^0.17.5",
"postcss": "^8.4.23",
"rollup": "^3.21.0"
"esbuild": "^0.18.10",
"postcss": "^8.4.25",
"rollup": "^3.25.2"
},
"bin": {
"vite": "bin/vite.js"
@@ -2155,12 +2263,16 @@
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
},
"peerDependencies": {
"@types/node": ">= 14",
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
"stylus": "*",
"sugarss": "*",
@@ -2173,6 +2285,9 @@
"less": {
"optional": true
},
"lightningcss": {
"optional": true
},
"sass": {
"optional": true
},
@@ -2204,6 +2319,18 @@
"peerDependencies": {
"vite": ">=2.0.0"
}
},
"node_modules/vscode-oniguruma": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
"integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
"dev": true
},
"node_modules/vscode-textmate": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
"integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
"dev": true
}
}
}
+2 -1
View File
@@ -22,11 +22,12 @@
],
"scripts": {
"dev": "vite",
"build": "node ./vite.build.js"
"build": "node ./vite.build.js && typedoc"
},
"devDependencies": {
"postcss-preset-env": "^8.2.0",
"sass": "^1.60.0",
"typedoc": "^0.24.8",
"vite": "^4.0.4",
"vite-plugin-externals": "^0.6.2"
}
+2 -1
View File
@@ -165,9 +165,10 @@ h1 {
#container {
flex: 1 1 auto;
overflow: auto;
padding: 20px;
>div {
padding: 20px;
margin-right: 20px;
}
}
+10
View File
@@ -0,0 +1,10 @@
{
"include": [
"./lib/functions*",
"./lib/ui/**/*"
],
"exclude": [
"./dist",
"node_modules"
]
}
+17
View File
@@ -0,0 +1,17 @@
{
"entryPoints": [
"lib/functions.d.ts",
"lib/ui/checkbox.d.ts",
"lib/ui/dropdown.d.ts",
"lib/ui/icon.d.ts",
"lib/ui/popup.d.ts",
"lib/ui/tooltip.d.ts",
"lib/ui/grid/column.d.ts",
"lib/ui/grid/grid.d.ts",
"lib/ui/media.d.ts"
],
"out": "./docs",
"readme": "README.md",
"name": "UI Library",
"cleanOutputDir": true
}