in-tree extjs-upload-widget

This commit is contained in:
gitadmin committed 2018-08-15 11:12:01 +03:00
1 parent 025b5f745e
commit 4635ee3492
46 files changed
+3166

No files matched your search

@@ -0,0 +1,153 @@
/**
* Abstract uploader object.
*
* The uploader object implements the the upload itself - transports data to the server. This is an "abstract" object
* used as a base object for all uploader objects.
*
*/
Ext.define('Ext.ux.upload.uploader.AbstractUploader', {
mixins : {
observable : 'Ext.util.Observable'
},
/**
* @cfg {Number} [maxFileSize=50000000]
*
* (NOT IMPLEMENTED) The maximum file size allowed to be uploaded.
*/
maxFileSize : 50000000,
/**
* @cfg {String} url (required)
*
* The server URL to upload to.
*/
url : '',
/**
* @cfg {Number} [timeout=60000]
*
* The connection timeout in miliseconds.
*/
timeout : 60 * 1000,
/**
* @cfg {String} [contentType='application/binary']
*
* The content type announced in the HTTP headers. It is autodetected if possible, but if autodetection
* cannot be done, this value is set as content type header.
*/
contentType : 'application/binary',
/**
* @cfg {String} [filenameHeader='X-File-Name']
*
* The name of the HTTP header containing the filename.
*/
filenameHeader : 'X-File-Name',
/**
* @cfg {String} [sizeHeader='X-File-Size']
*
* The name of the HTTP header containing the size of the file.
*/
sizeHeader : 'X-File-Size',
/**
* @cfg {String} [typeHeader='X-File-Type']
*
* The name of the HTTP header containing the MIME type of the file.
*/
typeHeader : 'X-File-Type',
/**
* @cfg {Object}
*
* Additional parameters to be sent with the upload request.
*/
params : {},
/**
* @cfg {Object}
*
* Extra headers to be sent with the upload request.
*/
extraHeaders : {},
/**
* @cfg {Object/String}
*
* Encoder object/class used to encode the filename header. Usually used, when the filename
* contains non-ASCII characters.
*/
filenameEncoder : null,
filenameEncoderHeader : 'X-Filename-Encoder',
/**
* Constructor.
* @param {Object} [config]
*/
constructor : function(config) {
this.mixins.observable.constructor.call(this);
this.initConfig(config);
},
/**
* @protected
*/
initHeaders : function(item) {
var headers = this.extraHeaders || {},
filename = item.getFilename();
/*
* If there is a filename encoder defined - use it to encode the filename
* in the header and set the type of the encoder as an additional header.
*/
var filenameEncoder = this.initFilenameEncoder();
if (filenameEncoder) {
filename = filenameEncoder.encode(filename);
headers[this.filenameEncoderHeader] = filenameEncoder.getType();
}
headers[this.filenameHeader] = filename;
headers[this.sizeHeader] = item.getSize();
headers[this.typeHeader] = item.getType();
return headers;
},
/**
* @abstract
*
* Upload a single item (file).
* **Implement in subclass**
*
* @param {Ext.ux.upload.Item} item
*/
uploadItem : function(item) {},
/**
* @abstract
*
* Aborts the current upload.
* **Implement in subclass**
*/
abortUpload : function() {},
/**
* @protected
*/
initFilenameEncoder : function() {
if (Ext.isString(this.filenameEncoder)) {
this.filenameEncoder = Ext.create(this.filenameEncoder);
}
if (Ext.isObject(this.filenameEncoder)) {
return this.filenameEncoder;
}
return null;
}
});
@@ -0,0 +1,44 @@
/**
* Abstract uploader with features common for all XHR based uploaders.
*/
Ext.define('Ext.ux.upload.uploader.AbstractXhrUploader', {
extend : 'Ext.ux.upload.uploader.AbstractUploader',
onUploadSuccess : function(response, options, item) {
var info = {
success : true,
message : '',
response : response
};
if (response.responseText) {
var responseJson = Ext.decode(response.responseText);
if (responseJson) {
Ext.apply(info, {
success : responseJson.success,
message : responseJson.message
});
var eventName = info.success ? 'uploadsuccess' : 'uploadfailure';
this.fireEvent(eventName, item, info);
return;
}
}
this.fireEvent('uploadsuccess', item, info);
},
onUploadFailure : function(response, options, item) {
var info = {
success : false,
message : 'http error',
response : response
};
this.fireEvent('uploadfailure', item, info);
},
onUploadProgress : function(event, item) {
this.fireEvent('uploadprogress', item, event);
}
});
@@ -0,0 +1,22 @@
Ext.define('Ext.ux.upload.uploader.DummyUploader', {
extend : 'Ext.ux.upload.uploader.AbstractUploader',
delay : 1000,
uploadItem : function(item) {
item.setUploading();
var task = new Ext.util.DelayedTask(function() {
this.fireEvent('uploadsuccess', item, {
success : true,
message : 'OK',
response : null
});
}, this);
task.delay(this.delay);
},
abortUpload : function() {
}
});
@@ -0,0 +1,133 @@
/**
* Uploader implementation - with the Connection object in ExtJS 4
*
*/
Ext.define('Ext.ux.upload.uploader.ExtJsUploader', {
extend : 'Ext.ux.upload.uploader.AbstractXhrUploader',
requires : [
'Ext.ux.upload.data.Connection'
],
config : {
/**
* @cfg {String} [method='PUT']
*
* The HTTP method to be used.
*/
method : 'PUT',
/**
* @cfg {Ext.data.Connection}
*
* If set, this connection object will be used when uploading files.
*/
connection : null
},
/**
* @property
* @private
*
* The connection object.
*/
conn : null,
/**
* @private
*
* Initializes and returns the connection object.
*
* @return {Ext.ux.upload.data.Connection}
*/
initConnection : function() {
var conn,
url = this.url;
if (this.connection instanceof Ext.data.Connection) {
conn = this.connection;
} else {
if (this.params) {
url = Ext.urlAppend(url, Ext.urlEncode(this.params));
}
conn = Ext.create('Ext.ux.upload.data.Connection', {
disableCaching : true,
method : this.method,
url : url,
timeout : this.timeout,
defaultHeaders : {
'Content-Type' : this.contentType,
'X-Requested-With' : 'XMLHttpRequest'
}
});
}
return conn;
},
/**
* @protected
*/
initHeaders : function(item) {
var headers = this.callParent(arguments);
headers['Content-Type'] = item.getType();
return headers;
},
/**
* Implements {@link Ext.ux.upload.uploader.AbstractUploader#uploadItem}
*
* @param {Ext.ux.upload.Item} item
*/
uploadItem : function(item) {
var file = item.getFileApiObject();
if (!file) {
return;
}
item.setUploading();
this.conn = this.initConnection();
/*
* Passing the File object directly as the "rawFata" option.
* Specs:
* https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#the-send()-method
* http://dev.w3.org/2006/webapi/FileAPI/#blob
*/
this.conn.request({
scope : this,
headers : this.initHeaders(item),
rawData : file,
success : Ext.Function.bind(this.onUploadSuccess, this, [
item
], true),
failure : Ext.Function.bind(this.onUploadFailure, this, [
item
], true),
progress : Ext.Function.bind(this.onUploadProgress, this, [
item
], true)
});
},
/**
* Implements {@link Ext.ux.upload.uploader.AbstractUploader#abortUpload}
*/
abortUpload : function() {
if (this.conn) {
/*
* If we don't suspend the events, the connection abortion will cause a failure event.
*/
this.suspendEvents();
this.conn.abort();
this.resumeEvents();
}
}
});
@@ -0,0 +1,87 @@
/**
* Uploader implementation which uses a FormData object to send files through XHR requests.
*
*/
Ext.define('Ext.ux.upload.uploader.FormDataUploader', {
extend : 'Ext.ux.upload.uploader.AbstractXhrUploader',
requires : [
'Ext.ux.upload.data.Connection'
],
method : 'POST',
xhr : null,
initConnection : function() {
if (this.params) {
this.url = Ext.urlAppend(this.url, Ext.urlEncode(this.params));
}
var xhr = new XMLHttpRequest(),
method = this.method,
url = this.url;
xhr.open(method, url, true);
this.abortXhr = function() {
this.suspendEvents();
xhr.abort();
this.resumeEvents();
};
return xhr;
},
uploadItem : function(item) {
var file = item.getFileApiObject();
item.setUploading();
var formData = new FormData();
formData.append(file.name, file);
var xhr = this.initConnection();
xhr.setRequestHeader(this.filenameHeader, file.name);
xhr.setRequestHeader(this.sizeHeader, file.size);
xhr.setRequestHeader(this.typeHeader, file.type);
var loadendhandler = Ext.Function.bind(this.onLoadEnd, this, [
item
], true);
var progresshandler = Ext.Function.bind(this.onUploadProgress, this, [
item
], true);
xhr.addEventListener('loadend', loadendhandler, true);
xhr.upload.addEventListener("progress", progresshandler, true);
xhr.send(formData);
},
/**
* Implements {@link Ext.ux.upload.uploader.AbstractUploader#abortUpload}
*/
abortUpload : function() {
this.abortXhr();
},
/**
* @protected
*
* A placeholder for the abort procedure.
*/
abortXhr : function() {
},
onLoadEnd : function(event, item) {
var response = event.target;
if (response.status != 200) {
return this.onUploadFailure(response, null, item);
}
return this.onUploadSuccess(response, null, item);
}
});
@@ -0,0 +1,127 @@
/**
* Uploader implementation - with the Connection object in ExtJS 4
*
*/
Ext.define('Ext.ux.upload.uploader.ExtJsUploader', {
extend : 'Ext.ux.upload.uploader.AbstractUploader',
requires : [
'Ext.ux.upload.data.Connection'
],
/**
* @property
*
* The connection object.
*/
conn : null,
/**
* @private
*
* Initializes and returns the connection object.
*
* @return {Ext.ux.upload.data.Connection}
*/
initConnection : function() {
var url = this.url;
if (this.params) {
url = Ext.urlAppend(url, Ext.urlEncode(this.params));
}
var conn = Ext.create('Ext.ux.upload.data.Connection', {
disableCaching : true,
method : this.method,
url : url,
timeout : this.timeout,
defaultHeaders : {
'Content-Type' : this.contentType,
'X-Requested-With' : 'XMLHttpRequest'
}
});
return conn;
},
/**
* Implements {@link Ext.ux.upload.uploader.AbstractUploader#uploadItem}
*
* @param {Ext.ux.upload.Item} item
*/
uploadItem : function(item) {
var file = item.getFileApiObject();
if (!file) {
return;
}
item.setUploading();
this.conn = this.initConnection();
this.conn.request({
scope : this,
headers : this.initHeaders(item),
xmlData : file,
success : Ext.Function.bind(this.onUploadSuccess, this, [
item
], true),
failure : Ext.Function.bind(this.onUploadFailure, this, [
item
], true),
progress : Ext.Function.bind(this.onUploadProgress, this, [
item
], true)
});
},
/**
* Implements {@link Ext.ux.upload.uploader.AbstractUploader#abortUpload}
*/
abortUpload : function() {
if (this.conn) {
this.conn.abort();
}
},
onUploadSuccess : function(response, options, item) {
var info = {
success : false,
message : 'general error',
response : response
};
if (response.responseText) {
var responseJson = Ext.decode(response.responseText);
if (responseJson && responseJson.success) {
Ext.apply(info, {
success : responseJson.success,
message : responseJson.message
});
this.fireEvent('uploadsuccess', item, info);
return;
}
Ext.apply(info, {
message : responseJson.message
});
}
this.fireEvent('uploadfailure', item, info);
},
onUploadFailure : function(response, options, item) {
var info = {
success : false,
message : 'http error',
response : response
};
this.fireEvent('uploadfailure', item, info);
},
onUploadProgress : function(event, item) {
this.fireEvent('uploadprogress', item, event);
}
});