in-tree extjs-upload-widget
This commit is contained in:
1 parent
025b5f745e
commit
4635ee3492
46 files changed
+3166
No files matched your search
+153
@@ -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;
|
||||
}
|
||||
|
||||
});
|
||||
+44
@@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
+87
@@ -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);
|
||||
}
|
||||
});
|
||||
+127
@@ -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);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user