UNPKG

dojox

Version:

Dojo eXtensions, a rollup of many useful sub-projects and varying states of maturity – from very stable and robust, to alpha and experimental. See individual projects contain README files for details.

171 lines (149 loc) 4.47 kB
define([ "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo", "dojo/request", "dojo/has" ],function(declare, lang, arrayUtil, dojo, request, has){ return declare("dojox.form.uploader._HTML5", [], { // summary: // A mixin for dojox/form/Uploader that adds HTML5 multiple-file upload capabilities and // progress events. // // description: // Note that this does not add these capabilities to browsers that don't support them. // For IE8 or older browsers, _IFrame or _Flash mixins will be used. // // debug message: errMsg:"Error uploading files. Try checking permissions", // Overwrites "form" and could possibly be overwritten again by iframe or flash plugin. uploadType:"html5", postMixInProperties: function(){ this.inherited(arguments); if(this.uploadType === "html5"){ } }, postCreate: function(){ this.connectForm(); this.inherited(arguments); if(this.uploadOnSelect){ this.connect(this, "onChange", function(data){ this.upload(data[0]); }); } }, _drop: function(e){ dojo.stopEvent(e); var dt = e.dataTransfer; this._files = dt.files; this.onChange(this.getFileList()); }, /************************* * Public Methods * *************************/ upload: function(/*Object ? */ formData){ // summary: // See: dojox.form.Uploader.upload this.onBegin(this.getFileList()); this.uploadWithFormData(formData); }, addDropTarget: function(node, /*Boolean?*/ onlyConnectDrop){ // summary: // Add a dom node which will act as the drop target area so user // can drop files to this node. // description: // If onlyConnectDrop is true, dragenter/dragover/dragleave events // won't be connected to dojo.stopEvent, and they need to be // canceled by user code to allow DnD files to happen. // This API is only available in HTML5 plugin (only HTML5 allows // DnD files). if(!onlyConnectDrop){ this.connect(node, 'dragenter', dojo.stopEvent); this.connect(node, 'dragover', dojo.stopEvent); this.connect(node, 'dragleave', dojo.stopEvent); } this.connect(node, 'drop', '_drop'); }, uploadWithFormData: function(/*Object*/ data){ // summary: // Used with WebKit and Firefox 4+ // Upload files using the much friendlier FormData browser object. // tags: // private if(!this.getUrl()){ console.error("No upload url found.", this); return; } var fd = new FormData(), fieldName=this._getFileFieldName(); arrayUtil.forEach(this._files, function(f, i){ fd.append(fieldName, f); }, this); if(data){ data.uploadType = this.uploadType; for(var nm in data){ fd.append(nm, data[nm]); } } var self = this; var deferred = request( this.getUrl(), { method: "POST", data: fd, handleAs: "json", uploadProgress: true, headers: { Accept: "application/json" } }, true ); deferred.promise.response .otherwise(function (error){ console.error(error); console.error(error.response.text); self.onError(error); }) ; function onProgressHandler(event){ self._xhrProgress(event); if(event.type !== "load"){ return; } self.onComplete(deferred.response.data); // Disconnect event handlers when done deferred.response.xhr.removeEventListener("load", onProgressHandler, false); deferred.response.xhr.upload.removeEventListener("progress", onProgressHandler, false); deferred = null; } if(has("native-xhr2")){ // Use addEventListener directly to pass the raw events to Uploader#_xhrProgress deferred.response.xhr.addEventListener("load", onProgressHandler, false); deferred.response.xhr.upload.addEventListener("progress", onProgressHandler, false); }else{ // If the browser doesn't have upload events, notify when the upload is complete deferred.promise.then(function(data){ self.onComplete(data); }); } }, _xhrProgress: function(evt){ if(evt.lengthComputable){ var o = { bytesLoaded:evt.loaded, bytesTotal:evt.total, type:evt.type, timeStamp:evt.timeStamp }; if(evt.type == "load"){ // 100% o.percent = "100%"; o.decimal = 1; }else{ o.decimal = evt.loaded / evt.total; o.percent = Math.ceil((evt.loaded / evt.total)*100)+"%"; } this.onProgress(o); } } }); });