9 lines
13 KiB
JavaScript
9 lines
13 KiB
JavaScript
/*!
|
|
App Connect S3 Upload
|
|
Version: 2.0.1
|
|
(c) 2025 Wappler.io
|
|
@build 2025-02-03 12:03:36
|
|
*/
|
|
dmx.Actions({"s3.upload":function(t){var e=this.parse(t.input),i=this.parse(t.url),s=document.getElementById(e).files[0];return new Promise((function(t,e){var r=new XMLHttpRequest;r.onerror=e,r.onabort=e,r.ontimeout=e,r.onload=t,r.open("PUT",i),r.setRequestHeader("Content-Type",s.type),r.send(s)}))}}),dmx.Component("s3-upload",{initialData:{data:null,file:null,state:{idle:!0,ready:!1,uploading:!1,done:!1},uploadProgress:{position:0,total:0,percent:0},lastError:{status:0,message:"",response:null}},attributes:{url:{type:String,default:null},prop:{type:String,default:"url"},accept:{type:String,default:null},autoupload:{type:Boolean,default:!1}},methods:{abort(){this.abort()},reset(){this.reset()},select(){this._input.click()},upload(){this.upload()}},events:{start:Event,done:Event,error:Event,abort:Event,success:Event,upload:ProgressEvent},init(){this._abortHandler=this._abortHandler.bind(this),this._errorHandler=this._errorHandler.bind(this),this._timeoutHandler=this._timeoutHandler.bind(this),this._loadHandler=this._loadHandler.bind(this),this._progressHandler=this._progressHandler.bind(this),this._dragoverHandler=this._dragoverHandler.bind(this),this._dropHandler=this._dropHandler.bind(this),this._clickHandler=this._clickHandler.bind(this),this._changeHandler=this._changeHandler.bind(this),this._xhr=new XMLHttpRequest,this._xhr.addEventListener("abort",this._abortHandler),this._xhr.addEventListener("error",this._errorHandler),this._xhr.addEventListener("timeout",this._timeoutHandler),this._xhr.addEventListener("load",this._loadHandler),this._xhr.upload.addEventListener("progress",this._progressHandler)},render(t){this.$node.addEventListener("dragover",this._dragoverHandler),this.$node.addEventListener("drop",this._dropHandler),this.$node.addEventListener("click",this._clickHandler),this._input=document.createElement("input"),this._input.type="file",this._input.accept=this.props.accept||"*/*",this._input.addEventListener("change",this._changeHandler),this.$parse()},performUpdate(t){t.has("accept")&&(this._input.accept=this.props.accept||"*/*")},destroy(){this._xhr.removeEventListener("abort",this._abortHandler),this._xhr.removeEventListener("error",this._errorHandler),this._xhr.removeEventListener("timeout",this._timeoutHandler),this._xhr.removeEventListener("load",this._loadHandler),this._xhr.upload.removeEventListener("progress",this._progressHandler),this.$node.removeEventListener("dragover",this._dragoverHandler),this.$node.removeEventListener("drop",this._dropHandler),this.$node.removeEventListener("click",this._clickHandler),this._input.removeEventListener("change",this._changeHandler),this._xhr=null,this._input=null},_validate(t){return!this.props.accept||this.props.accept.split(/\s*,\s*/g).some((e=>{if("."==e.charAt(0)){if(t.name.match(new RegExp("\\"+e+"$","i")))return!0}else if(/(audio|video|image)\/\*/i.test(e)){if(t.type.match(new RegExp("^"+e.replace(/\*/g,".*")+"$","i")))return!0}else if(t.type.toLowerCase()==e.toLowerCase())return!0;return!1}))},updateFile(t){if(!this._validate(t))return;const e={name:t.name,size:t.size,type:t.type,date:(t.lastModified?new Date(t.lastModified):t.lastModifiedDate).toISOString(),dataUrl:null};-1===t.type.indexOf("image/")||t.reader||(t.reader=new FileReader,t.reader.onload=t=>{e.dataUrl=t.target.result,this.set("file",{...e})},t.reader.readAsDataURL(t)),this.file=t,this.set({file:e,state:{idle:!1,ready:!0,uploading:!1,done:!1}}),this.props.autoupload&&this.upload()},abort(){this._xhr.abort()},reset(){this.abort(),this.file=null,this.set({data:null,file:null,state:{idle:!0,ready:!1,uploading:!1,done:!1},uploadProgress:{position:0,total:0,percent:0},lastError:{status:0,message:"",response:null}})},upload(){if(!this.props.url)return void this.onError("No url attribute is set");this.set({state:{idle:!1,ready:!1,uploading:!0,done:!1}}),this.dispatchEvent("start");const t=new XMLHttpRequest;t.onabort=this._abortHandler,t.onerror=this._errorHandler,t.onload=()=>this.upload2(t),t.open("GET",this.props.url+"?name="+encodeURIComponent(this.file.name)),t.send()},upload2(t){try{const i=JSON.parse(t.responseText),s=i[this.props.prop];if(this.set("data",i),this._xhr.open("PUT",s),this._xhr.setRequestHeader("Content-Type",this.file.type),-1!=s.indexOf("x-amz-acl=")){var e=s.substr(s.indexOf("x-amz-acl=")+10);-1!=e.indexOf("&")&&(e=e.substr(0,e.indexOf("&"))),this._xhr.setRequestHeader("x-amz-acl",e)}this._xhr.send(this.file)}catch(t){this._errorHandler(t)}},_abortHandler(t){this.set({data:null,state:{idle:!1,ready:!0,uploading:!1,done:!1},uploadProgress:{position:0,total:0,percent:0}}),this.dispatchEvent("abort"),this.dispatchEvent("done")},_errorHandler(t){t instanceof ProgressEvent&&(t="Network error, perhaps no CORS set"),this.set({data:null,state:{idle:!1,ready:!0,uploading:!1,done:!1},uploadProgress:{position:0,total:0,percent:0},lastError:{status:0,message:t.message||t,response:null}}),console.error(t),this.dispatchEvent("error"),this.dispatchEvent("done")},_timeoutHandler(t){this._errorHandler("Execution timeout")},_loadHandler(t){this._xhr.status>=400?this._errorHandler(this._xhr.responseText):(this.set({state:{idle:!1,ready:!1,uploading:!1,done:!0},uploadProgress:{position:this.file.size,total:this.file.size,percent:100}}),this.dispatchEvent("success"),this.dispatchEvent("done"))},_progressHandler(t){this.set({state:{idle:!1,ready:!1,uploading:!0,done:!1},uploadProgress:{position:t.loaded,total:this.file.size,percent:Math.ceil(t.loaded/t.total*100)}}),this.dispatchEvent("upload",{lengthComputable:t.lengthComputable,loaded:t.loaded,total:t.total})},_dragoverHandler(t){t.stopPropagation(),t.preventDefault(),t.dataTransfer.dropEffect=1==t.dataTransfer.items.length?"copy":"none"},_dropHandler(t){t.stopPropagation(),t.preventDefault(),1==t.dataTransfer.files.length&&this.updateFile(t.dataTransfer.files[0])},_clickHandler(t){this._input.click()},_changeHandler(t){this.updateFile(t.target.files[0]),this._input.value="",this._input.type="",this._input.type="file"}}),dmx.Component("s3-upload-multi",{initialData:{data:null,files:[],state:{idle:!0,ready:!1,uploading:!1},lastError:""},attributes:{url:{type:String,default:null},prop:{type:String,default:"url"},accept:{type:String,default:null},autoupload:{type:Boolean,default:!1},thumbs:{type:String,default:"true"},thumbWidth:{type:Number,default:100},thumbHeight:{type:Number,default:100}},methods:{abort(){this.abort()},reset(){this.reset()},select(){this.input.click()},remove(t){this.remove(t)},upload(){this.startUpload()}},events:{start:Event,done:Event,error:Event,abort:Event,success:Event},render(t){this.$node.addEventListener("dragover",this.onDragover.bind(this)),this.$node.addEventListener("drop",this.onDrop.bind(this)),this.$node.addEventListener("click",this.onClick.bind(this)),this.input=document.createElement("input"),this.input.type="file",this.input.multiple=!0,this.input.accept=this.props.accept||"*/*",this.input.addEventListener("change",this.onChange.bind(this)),this.maxRetries=5,this.uploads=[],this.ii=0,this.$parse()},performUpdate(t){t.has("accept")&&(this.input.accept=this.props.accept||"*/*")},isUploading(){return!!this.uploads.find((function(t){return t.info.uploading}),this)},nextRetry(t){return 3e3*(this.maxRetries-t+1)},_updateData(){this.set("files",[...this.data.files]),this.uploads.length?this.isUploading()?this.set("state",{idle:!1,ready:!1,uploading:!0}):this.set("state",{idle:!1,ready:!0,uploading:!1}):this.set("state",{idle:!0,ready:!1,uploading:!1})},_validate(t){return!this.props.accept||this.props.accept.split(/\s*,\s*/g).some((function(e){if("."==e.charAt(0)){if(t.name.match(new RegExp("\\"+e+"$","i")))return!0}else if(/(audio|video|image)\/\*/i.test(e)){if(t.type.match(new RegExp("^"+e.replace(/\*/g,".*")+"$","i")))return!0}else if(t.type.toLowerCase()==e.toLowerCase())return!0;return!1}))},onDragover(t){t.stopPropagation(),t.preventDefault(),t.dataTransfer.dropEffect="copy"},onDrop(t){if(t.stopPropagation(),t.preventDefault(),t.dataTransfer){var e=t.dataTransfer.files;if(e.length){var i=t.dataTransfer.items;i&&i.length&&i[0].webkitGetAsEntry?this.updateFilesFromItems(i):this.updateFiles(e)}}},onClick(t){this.input.click()},onChange(t){this.updateFiles(t.target.files),this.input.value="",this.input.type="",this.input.type="file"},onAbort(t,e){t.info.uploading=!1,t.info.uploaded=0,t.info.percent=0,this._updateData(),this.isUploading()||(this.dispatchEvent("abort"),this.dispatchEvent("done"))},onError(t,e){t.url&&t.retries?setTimeout(this.upload3.bind(this,t),this.nextRetry(t.retries--)):(e=e instanceof ProgressEvent?"Network error, perhaps no CORS set":e.message||e,this.set("lastError",e),t.info.uploading=!1,t.info.uploaded=0,t.info.percent=0,t.info.error=e,this._updateData(),this.isUploading()||(this.dispatchEvent("error"),this.dispatchEvent("done")))},onTimeout(t,e){this.onError(t,"Execution timeout")},onLoad(t,e){t.xhr.status>=500||429==t.xhr.status?t.retries?setTimeout(this.upload3.bind(this,t),this.nextRetry(t.retries--)):this.onError(t,t.xhr.responseText||t.xhr.statusText):t.xhr.status>=400?this.onError(t,t.xhr.responseText||t.xhr.statusText):(this.remove(t.file.id),this._updateData(),this.isUploading()||(this.uploads.length?this.dispatchEvent("error"):this.dispatchEvent("success"),this.dispatchEvent("done")))},onProgress(t,e){t.info.uploaded=e.loaded,t.info.percent=e.lengthComputable?Math.ceil(e.loaded/e.total*100):0,this._updateData()},resize(t,e){var i=document.createElement("img"),s=parseInt(this.props["thumb-width"])||100,r=parseInt(this.props["thumb-height"])||100;i.onload=function(){var t=document.createElement("canvas"),a=t.getContext("2d"),n=i.width,o=i.height;s=Math.min(s,n),r=Math.min(r,o);var d=s/r;(n>s||o>r)&&(n/o>d?n=o*d:o=n/d),t.width=s,t.height=r;var l=(i.width-n)/2,h=(i.height-o)/2;a.drawImage(i,l,h,n,o,0,0,s,r),e(t.toDataURL())},i.src=t},updateFile(t){if(this._validate(t)){t.id=++this.ii;var e={id:t.id,name:t.name,size:t.size,type:t.type,date:(t.lastModified?new Date(t.lastModified):t.lastModifiedDate).toISOString(),data:null,uploading:!1,uploaded:0,percent:0,ready:!1,error:null,dataUrl:null};-1===t.type.indexOf("image/")||t.reader?e.ready=!0:(t.reader=new FileReader,t.reader.onload=t=>{e.dataUrl=t.target.result,this.props.thumbs?this.resize(e.dataUrl,(t=>{e.dataUrl=t,e.ready=!0,this.set("files",[...this.data.files])})):e.ready=!0,this._updateData()},t.reader.readAsDataURL(t));var i={retries:this.maxRetries,info:e,file:t,xhr:null};this.uploads.push(i),this.set({files:this.data.files.concat([e]),state:{idle:!1,ready:!0,uploading:!1,done:!1}}),this.props.autoupload&&(this.isUploading()||this.dispatchEvent("start"),this.upload(i))}},updateFiles(t){dmx.array(t).forEach((t=>{this.updateFile(t)}))},updateFilesFromItems(t){dmx.array(t).forEach((t=>{var e;t.webkitGetAsEntry&&(e=t.webkitGetAsEntry())?e.isFile?this.updateFile(t.getAsFile()):e.isDirectory&&this.updateFilesFromDirectory(e):t.getAsFile&&(t.kind&&"file"!=t.kind||this.updateFile(t.getAsFile()))}))},updateFilesFromDirectory(t,e){var i=t.createReader(),s=function(){i.readEntries(function(t){t.length&&t.forEach((function(t){t.isFile?t.file(function(t){t.fullPath=e+"/"+t.name,this.updateFile(t)}.bind(this)):t.isDirectory&&this.updateFilesFromDirectory(t,e+"/"+t.name)}),this),s()}.bind(this),function(t){console.warn(t)}.bind(this))}.bind(this);s()},abort(){this.uploads.forEach((t=>{t.xhr&&t.xhr.abort()}))},reset(){this.abort(),this.uploads=[],this.set({data:null,files:[],state:{idle:!0,ready:!1,uploading:!1},lastError:""})},remove(t){var e=this.uploads.findIndex((e=>e.file.id==t));-1!=e&&(this.uploads[e].xhr&&this.uploads[e].xhr.abort(),this.uploads.splice(e,1),this.data.files.splice(e,1),this._updateData())},startUpload(){this.dispatchEvent("start"),this.uploads.forEach((t=>{this.upload(t)}),this)},upload(t){t.info&&t.info.uploading||(this.props.url?(this.set({state:{idle:!1,ready:!1,uploading:!0,done:!1}}),t.info.uploading=!0,this.set("files",[...this.data.files]),t.xhr=new XMLHttpRequest,t.xhr.onabort=this.onAbort.bind(this,t),t.xhr.onerror=this.onError.bind(this,t),t.xhr.ontimeout=this.onTimeout.bind(this,t),t.xhr.onload=this.upload2.bind(this,t),t.xhr.open("GET",this.props.url+"?name="+encodeURIComponent(t.file.name)),t.xhr.send()):this.onError("No url attribute is set"))},upload2(t){try{t.info.data=JSON.parse(t.xhr.responseText),t.url=t.info.data[this.props.prop],t.xhr.onload=this.onLoad.bind(this,t),t.xhr.upload.addEventListener("progress",this.onProgress.bind(this,t)),this.upload3(t)}catch(e){this.onError(t,e)}},upload3(t){try{if(t.xhr.open("PUT",t.url),t.xhr.setRequestHeader("Content-Type",t.file.type),-1!=t.url.indexOf("x-amz-acl=")){var e=t.url.substr(t.url.indexOf("x-amz-acl=")+10);-1!=e.indexOf("&")&&(e=e.substr(0,e.indexOf("&"))),t.xhr.setRequestHeader("x-amz-acl",e)}t.xhr.send(t.file)}catch(e){t.retries?(console.log("Retry upload",t),setTimeout(this.upload3.bind(this,t),this.nextRetry(t.retries--))):(console.log("Error in upload",t,e),this.onError(t,e))}}});
|
|
//# sourceMappingURL=dmxS3Upload.js.map
|