This commit is contained in:
2024-11-05 10:47:20 -07:00
parent c801b1ff51
commit 5315c47fcd
276 changed files with 2990 additions and 6370 deletions

View File

@@ -2,6 +2,11 @@
// Utils
Sys.Extended.UI.AjaxFileUpload.Utils = function() {
function getExtension(filename) {
var extensionStartIndex = filename.lastIndexOf('.') + 1;
return extensionStartIndex ? filename.substring(extensionStartIndex) : "";
}
this.generateGuid = function() {
var result, i, j;
@@ -41,7 +46,7 @@ Sys.Extended.UI.AjaxFileUpload.Utils = function() {
}
}
return encodeURIComponent(result);
return result;
};
this.getFileType = function(file) {
@@ -49,7 +54,7 @@ Sys.Extended.UI.AjaxFileUpload.Utils = function() {
throw 'file must defined or not null';
if(!file.value && file.name)
return file.name.substring(file.name.lastIndexOf('.') + 1);
return getExtension(file.name);
if(file.value)
file = file.value;
@@ -57,7 +62,7 @@ Sys.Extended.UI.AjaxFileUpload.Utils = function() {
if(typeof (file) !== "string")
throw "can't resolve file type.";
return file.substring(file.lastIndexOf('.') + 1);
return getExtension(file);
};
this.sizeToString = function(bytes) {
@@ -155,18 +160,19 @@ Sys.Extended.UI.AjaxFileUpload.Item.prototype = {
});
this._fileName = utils.getFileName(file);
var fileNameToDisplay = decodeURIComponent(this._fileName);
var htmlEncode = Sys.Extended.UI.htmlEncode;
if(isHtml5Support) {
this._fileSize = file.size;
var fType = file.type ? '<span class="filetype">(' + file.type + ')</span>' : '';
fileInfoText.innerHTML = '<span class="filename">' + fileNameToDisplay + '</span> '
var fType = file.type ? '<span class="filetype">(' + htmlEncode(file.type) + ')</span>' : '';
fileInfoText.innerHTML = '<span class="filename">' + htmlEncode(this._fileName) + '</span> '
+ fType
+ ' - <span class="filesize">' + utils.sizeToString(file.size) + '</span> ';
this._fileType = file.type;
} else {
fileInfoText.innerHTML = '<span class="filename">' + fileNameToDisplay + '</span>';
fileInfoText.innerHTML = '<span class="filename">' + htmlEncode(this._fileName) + '</span>';
this._fileType = utils.getFileType(file);
}
@@ -302,13 +308,19 @@ Sys.Extended.UI.AjaxFileUpload.Processor = function(control, elements) {
};
if(control.fileTypeIsValid(fileItem.type)) {
control.addFileToQueue(fileItem);
this.createInputFileElement();
} else {
if(!control.fileTypeIsValid(fileItem.type)) {
control.confirmFileIsInvalid(fileItem);
return;
}
if(control.fileSizeExceeded(fileItem.value.size)) {
control.confirmFileIsTooLarge(fileItem);
return;
}
control.addFileToQueue(fileItem);
this.createInputFileElement();
};
this.createInputFileElement = function() {
@@ -331,7 +343,8 @@ Sys.Extended.UI.AjaxFileUpload.Processor = function(control, elements) {
zIndex: 0,
cursor: 'pointer',
position: 'absolute'
}
},
multiple: true
}
}, currentInputFile.parentNode);
@@ -374,7 +387,12 @@ Sys.Extended.UI.AjaxFileUpload.Processor = function(control, elements) {
// only add 1 file input element to be uploaded
form.appendChild(inputElement);
form.setAttribute("action", control._uploadUrl + '?contextKey=' + control.get_id() + '&fileId=' + control._currentFileId + '&fileName=' + fileItem._fileName + '&usePoll=' + (control.get_serverPollingSupport() ? "true" : "false"));
form.setAttribute("action", control.get_uploadHandlerPath()
+ '?contextKey=' + control.get_contextKey()
+ '&controlID=' + control.get_id()
+ '&fileId=' + control._currentFileId
+ '&fileName=' + encodeURIComponent(fileItem._fileName)
+ '&usePoll=' + (control.get_serverPollingSupport() ? "true" : "false"));
// upload it now
form.submit();
@@ -389,7 +407,12 @@ Sys.Extended.UI.AjaxFileUpload.Processor = function(control, elements) {
if(xhrPoll)
xhrPoll.abort();
xhr.open("POST", '?contextKey=' + control.get_id() + "&cancel=1&guid=" + control._currentFileId, true);
xhr.open("POST",
'?contextKey=' + control.get_contextKey()
+ '&controlID=' + control.get_id()
+ '&cancel=1&guid=' + control._currentFileId
+ self.getQueryString(), true);
xhr.onreadystatechange = function() {
self.setThrobber(false);
if(xhr.readyState == 4) {
@@ -405,6 +428,10 @@ Sys.Extended.UI.AjaxFileUpload.Processor = function(control, elements) {
xhr.send(null);
},
this.getQueryString = function() {
return "&" + window.location.search.replace("?", "");
},
this.createIFrame = function() {
var name = this._iframeName,
@@ -486,7 +513,10 @@ Sys.Extended.UI.AjaxFileUpload.Processor = function(control, elements) {
if(!value || !control._currentFileId)
return;
xhrPoll.open("GET", '?contextKey=' + control.get_id() + "&poll=1&guid=" + control._currentFileId, true);
xhrPoll.open("GET",
'?contextKey=' + control.get_contextKey()
+ '&controlID=' + control.get_id()
+ '&poll=1&guid=' + control._currentFileId, true);
xhrPoll.send(null);
};
@@ -516,13 +546,16 @@ Sys.Extended.UI.AjaxFileUpload.Processor = function(control, elements) {
this.raiseUploadError = function(xhr) {
control.raise_uploadError(xhr);
control.setFileStatus(control._currentFileId, 'error', Sys.Extended.UI.Resources.AjaxFileUpload_error);
if(xhrPoll)
xhrPoll.abort();
control._currentFileId = null;
};
this.resetUI = function() {
control.setFileStatus(control._currentFileId, 'error', Sys.Extended.UI.Resources.AjaxFileUpload_error);
};
};
// ProcessorHtml5
@@ -557,7 +590,16 @@ Sys.Extended.UI.AjaxFileUpload.ProcessorHtml5 = function(control, elements) {
this.onFileDroppedHandler = function(e) {
e.stopPropagation();
e.preventDefault();
if(!control.get_enabled())
return;
this.addFilesToQueue(e.dataTransfer.files);
if (control.get_autoStartUpload()) {
control.startUpload();
}
};
this.onFileDragOverHandler = function(e) {
@@ -568,11 +610,15 @@ Sys.Extended.UI.AjaxFileUpload.ProcessorHtml5 = function(control, elements) {
this.onFileSelectedHandler = function(e) {
this.addFilesToQueue(e.target.files);
this.createInputFileElement();
if (control.get_autoStartUpload()) {
control.startUpload();
}
};
this.createInputFileElement = function() {
var currentInputFile = elements.inputFile;
delete currentInputFile;
// create new input file element in same location
@@ -587,7 +633,8 @@ Sys.Extended.UI.AjaxFileUpload.ProcessorHtml5 = function(control, elements) {
zIndex: 0,
cursor: 'pointer',
position: 'absolute'
}
},
multiple: true
}
}, currentInputFile.parentNode);
@@ -607,10 +654,10 @@ Sys.Extended.UI.AjaxFileUpload.ProcessorHtml5 = function(control, elements) {
// #endregion
this.addFilesToQueue = function(files) {
// Validate and generate file item from HTML5 files.
this.addFilesToQueue = function (files) {
for(var i = 0; i < files.length; i++) {
// Validate and generate file item from HTML5 files.
for (var i = 0; i < files.length; i++) {
var blob = files[i],
slices = 0;
@@ -630,12 +677,19 @@ Sys.Extended.UI.AjaxFileUpload.ProcessorHtml5 = function(control, elements) {
};
// validate it, add it if it's OK
if(control.fileTypeIsValid(fileItem.type)) {
if(!control.addFileToQueue(fileItem))
break;
} else {
if(!control.fileTypeIsValid(fileItem.type)) {
control.confirmFileIsInvalid(fileItem);
continue;
}
if(control.fileSizeExceeded(fileItem.value.size))
{
control.confirmFileIsTooLarge(fileItem);
continue;
}
if(!control.addFileToQueue(fileItem))
break;
}
// reset input file value so 'change' event can be fired again with same file name.
@@ -668,6 +722,15 @@ Sys.Extended.UI.AjaxFileUpload.ProcessorHtml5 = function(control, elements) {
}
};
this.resetUI = function() {
$common.setVisible(elements.progressBarContainer, false);
$common.setVisible(control._elements.uploadOrCancelButton, false);
var fileItem = control.getNextFile();
fileItem._isUploaded = true;
fileItem._isUploading = false;
},
this.upload = function(fileItem) {
if(!control._isUploading)
return;
@@ -680,7 +743,6 @@ Sys.Extended.UI.AjaxFileUpload.ProcessorHtml5 = function(control, elements) {
// preparing upload data
var blob = fileItem.get_inputElementValue(),
fileName = fileItem._fileName,
chunked = fileItem._slices && (fileItem._slices > 0),
firstChunk = fileItem._sliceIndex == 0;
@@ -701,7 +763,15 @@ Sys.Extended.UI.AjaxFileUpload.ProcessorHtml5 = function(control, elements) {
xhrReq.addEventListener("load", xhrDelegate(this.onUploadCompleteHandler), false);
xhrReq.addEventListener("error", xhrDelegate(this.onUploadFailedHandler), false);
xhrReq.addEventListener("abort", xhrDelegate(this.onUploadCanceledHandler), false);
xhrReq.open("POST", control._uploadUrl + '?contextKey=' + control.get_id() + '&fileId=' + id + '&fileName=' + fileName + '&chunked=' + (chunked ? "true" : "false") + '&firstChunk=' + firstChunk, true);
xhrReq.open("POST",
control.get_uploadHandlerPath()
+ '?contextKey=' + control.get_contextKey()
+ '&controlID=' + control.get_id()
+ '&fileId=' + id
+ '&fileName=' + encodeURIComponent(fileItem._fileName)
+ '&chunked=' + (chunked ? "true" : "false")
+ '&firstChunk=' + firstChunk, true);
form.append("act-file-data", blob);
xhrReq.send(form);
};
@@ -761,7 +831,7 @@ Sys.Extended.UI.AjaxFileUpload.ProcessorHtml5 = function(control, elements) {
// set statuses as uploaded
fileItem.setStatus('uploaded', Sys.Extended.UI.Resources.AjaxFileUpload_Uploaded);
control.setStatusMessage(String.format(Sys.Extended.UI.Resources.AjaxFileUpload_UploadingHtml5File,
file.name, utils.sizeToString(file.size)));
Sys.Extended.UI.htmlEncode(file.name), utils.sizeToString(file.size)));
// finalizing and upload next file
control.doneAndUploadNextFile(fileItem);
@@ -896,13 +966,24 @@ Sys.Extended.UI.AjaxFileUpload.Control = function(element) {
this._postBackUrl = null;
/// <summary>
/// How AjaxFileUpload displays a progress bar.
/// Specifies how AjaxFileUpload uploads files.
/// If set to Auto or Client and the client browser supports HTML 5, AjaxFileUpload uploads files using AJAX requests.
/// If set to Server or the browser does not support HTML 5, AjaxFileUpload uploads files by posting the HTML form.
/// The default is Auto.
/// </summary>
/// <getter>get_mode</getter>
/// <setter>set_mode</setter>
/// <member name="cP:AjaxControlToolkit.AjaxFileUpload.mode" />
this._mode = 0;
/// <summary>
/// Whether or not automatically start upload files after drag/drop or select in file dialog. The default is false
/// </summary>
/// <getter>get_autoStartUpload</getter>
/// <setter>set_autoStartUpload</setter>
/// <member name="cP:AjaxControlToolkit.AjaxFileUpload.autoStartUpload" />
this._autoStartUpload = false;
/// <summary>
/// Whether or not AjaxFileUpload supports server polling.
/// </summary>
@@ -947,8 +1028,37 @@ Sys.Extended.UI.AjaxFileUpload.Control = function(element) {
this._clearFileListAfterUpload = false;
// fields
this._uploadUrl = 'AjaxFileUploadHandler.axd';
/// <summary>
/// Whether or not to use absolute path for AjaxFileUploadHandler
/// </summary>
/// <getter>get_useAbsoluteHandlerPath</getter>
/// <setter>set_useAbsoluteHandlerPath</setter>
/// <member name="cP:AjaxControlToolkit.AjaxFileUpload.useAbsoluteHandlerPath" />
this._useAbsoluteHandlerPath = true;
/// <summary>
/// The maximum size of a file to be uploaded in Kbytes.
/// A non-positive value means the size is unlimited.
/// </summary>
/// <getter>get_maxFileSize</getter>
/// <setter>set_maxFileSize</setter>
/// <member name="cP:AjaxControlToolkit.AjaxFileUpload.maxFileSize" />
this._maxFileSize = 0;
/// <summary>
/// The path to the upload handler.
/// </summary>
/// <getter>get_uploadHandlerPath</getter>
/// <setter>set_uploadHandlerPath</setter>
/// <member name="cP:AjaxControlToolkit.AjaxFileUpload.uploadHandlerPath" />
this._uploadHandlerPath = '';
/// <summary>
/// Whether the control is enabled.
/// </summary>
/// <getter>get_enabled</getter>
/// <setter>set_enabled</setter>
/// <member name="cP:AjaxControlToolkit.AjaxFileUpload.enabled" />
this._enabled = true;
this._useHtml5Support = false;
this._elements = null;
this._processor = null;
@@ -1055,6 +1165,10 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
},
_onUploadOrCancelButtonClickedHandler: function(e) {
var files = this._filesInQueue;
if(!this.validateFiles(files))
return;
if(!files.length) {
alert(Sys.Extended.UI.Resources.AjaxFileUpload_SelectFileToUpload);
return;
@@ -1083,8 +1197,11 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
var xhr = new XMLHttpRequest(),
self = this;
xhr.open("POST", '?contextKey=' + this.get_id()
+ "&start=1&queue=" + this._filesInQueue.length);
xhr.open("POST",
'?contextKey=' + this.get_contextKey()
+ '&controlID=' + this.get_id()
+ '&start=1&queue=' + this._filesInQueue.length
+ this.getQueryString());
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
@@ -1092,6 +1209,7 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
self.raise_uploadStart(Sys.Serialization.JavaScriptSerializer.deserialize(xhr.responseText));
} else {
self.raise_uploadError(xhr);
self.setFileStatus(fileItem, 'error', Sys.Extended.UI.Resources.AjaxFileUpload_error);
throw "Failed to starting upload.";
}
}
@@ -1111,6 +1229,30 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
}
},
/// <summary>
/// Validates files in queue before uploading.
/// Returns true if validation is passed, otherwise false
/// </summary>
/// <member name="cM:AjaxControlToolkit.AjaxFileUpload.validateFiles" />
/// <param name="files" type="Object">An array of files in the upload queue</param>
validateFiles: function(files)
{
return true;
},
/// <summary>
/// Manually starts upload process
/// </summary>
/// <member name="cM:AjaxControlToolkit.AjaxFileUpload.startUpload" />
startUpload: function () {
if (this._isUploading || !this._filesInQueue.length) {
return;
}
this._onUploadOrCancelButtonClickedHandler();
},
/// <summary>
/// If set to true, it will set the control state to enabled (ready to upload),
/// otherwise the control will be disabled and the button state turns to the Cancel button.
@@ -1147,10 +1289,13 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
self = this,
currentFile = this._filesInQueue[this._currentQueueIndex - 1];
xhr.open("POST", '?contextKey=' + this.get_id()
+ "&complete=1&queue=" + this._filesInQueue.length
+ "&uploaded=" + (this._currentQueueIndex - (currentFile._isUploaded ? 0 : 1))
+ "&reason=" + (this._canceled ? "cancel" : "done"));
xhr.open("POST",
'?contextKey=' + this.get_contextKey()
+ '&controlID=' + this.get_id()
+ '&complete=1&queue=' + this._filesInQueue.length
+ '&uploaded=' + (this._currentQueueIndex - (currentFile._isUploaded ? 0 : 1))
+ '&reason=' + (this._canceled ? "cancel" : "done")
+ this.getQueryString());
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
@@ -1158,12 +1303,13 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
self.raise_uploadCompleteAll(Sys.Serialization.JavaScriptSerializer.deserialize(xhr.responseText));
} else {
self.raise_uploadError(xhr);
self.setFileStatus(fileItem, 'error', Sys.Extended.UI.Resources.AjaxFileUpload_error);
throw "Failed to completing upload.";
}
}
};
xhr.send(null);
if(this.get_clearFileListAfterUpload()) {
for(var i = 0; i < this._filesInQueue.length; i += 1) {
var item = this._filesInQueue[i];
@@ -1272,16 +1418,43 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
return false;
},
/// <summary>
/// Checks if the file size is larger than the upload size limit.
/// </summary>
/// <member name="cM:AjaxControlToolkit.AjaxFileUpload.fileSizeExceeded" />
/// <param name="fileSize" type="Number">File size in bytes</param>
fileSizeExceeded: function(fileSize) {
if(this.get_maxFileSize() <= 0)
return false;
return fileSize > this.getMaxFileSizeInBytes();
},
/// <summary>
/// Sends alert to a user that the file type is not acceptable. The processor uses this method after validation.
/// </summary>
/// <member name="cM:AjaxControlToolkit.AjaxFileUpload.confirmFileIsInvalid" />
/// <param name="fileItem" type="Object">File trying to be added to queue</param>
/// <param name="fileItem" type="Object">A file attempting to be added to the upload queue.</param>
confirmFileIsInvalid: function(fileItem) {
var utils = new Sys.Extended.UI.AjaxFileUpload.Utils();
alert(String.format(Sys.Extended.UI.Resources.AjaxFileUpload_WrongFileType, utils.getFileName(fileItem.value), fileItem.type));
},
/// <summary>
/// Sends alert to a user that the file size is too large. The processor uses this method after validation.
/// </summary>
/// <member name="cM:AjaxControlToolkit.AjaxFileUpload.confirmFileIsTooLarge" />
/// <param name="fileItem" type="Object">A file attempting to be added to the upload queue.</param>
confirmFileIsTooLarge: function(fileItem) {
var utils = new Sys.Extended.UI.AjaxFileUpload.Utils();
alert(String.format(Sys.Extended.UI.Resources.AjaxFileUpload_TooLargeFile, utils.getFileName(fileItem.value), this.get_maxFileSize()));
},
getMaxFileSizeInBytes: function()
{
return this.get_maxFileSize() * 1024;
},
/// <summary>
/// Marks fileItem as uploaded, and uploads the next file in a queue.
/// </summary>
@@ -1292,10 +1465,15 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
var xhr = new XMLHttpRequest(),
self = this;
xhr.open("POST", "?contextKey=" + this.get_id() + "&done=1&guid=" + fileItem._id, true);
xhr.open("POST",
'?contextKey=' + this.get_contextKey()
+ '&controlID=' + this.get_id()
+ '&done=1&guid=' + fileItem._id
+ this.getQueryString(), true);
xhr.onreadystatechange = function(e) {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
if(xhr.status == 200 && xhr.responseText != "") {
// Mark as done and invoke event handler
self.raise_uploadComplete(Sys.Serialization.JavaScriptSerializer.deserialize(xhr.responseText));
@@ -1311,7 +1489,11 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
}
}
};
xhr.send(null);
xhr.send();
},
getQueryString: function() {
return "&" + window.location.search.replace("?", "");
},
/// <summary>
@@ -1349,7 +1531,7 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
this._currentQueueIndex = Array.indexOf(this._filesInQueue, fileItem) + 1;
this.setFileStatus(fileItem, 'uploading', Sys.Extended.UI.Resources.AjaxFileUpload_Uploading);
this.setStatusMessage('Uploading ' + this._currentQueueIndex + ' of ' + this._filesInQueue.length + ' file(s)');
this.setStatusMessage(String.format(Sys.Extended.UI.Resources.AjaxFileUpload_UploadingFileInQueue, this._currentQueueIndex, this._filesInQueue.length));
},
/// <summary>
@@ -1419,6 +1601,13 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
this._mode = value;
},
get_autoStartUpload: function () {
return this._autoStartUpload;
},
set_autoStartUpload: function (value) {
this._autoStartUpload = value;
},
get_serverPollingSupport: function() {
return this._serverPollingSupport;
},
@@ -1449,7 +1638,7 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
/// <summary>
/// Whether or not to hide the file upload list container after uploading finished
/// </summary
/// </summary>
/// <getter>get_clearQueueContainerAfterUpload</getter>
/// <setter>set_clearQueueContainerAfterUpload</setter>
/// <member name="cP:AjaxControlToolkit.AjaxFileUpload.clearQueueContainerAfterUpload" />
@@ -1460,6 +1649,33 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
this._clearFileListAfterUpload = value;
},
get_useAbsoluteHandlerPath: function() {
return this._useAbsoluteHandlerPath;
},
set_useAbsoluteHandlerPath: function(value) {
this._useAbsoluteHandlerPath = value;
},
get_maxFileSize: function() {
return this._maxFileSize;
},
set_maxFileSize: function(value) {
this._maxFileSize = value;
},
get_uploadHandlerPath: function () {
return this._uploadHandlerPath;
},
set_uploadHandlerPath: function (value) {
this._uploadHandlerPath = value;
},
get_enabled: function () {
return this.enabled;
},
set_enabled: function (value) {
this.enabled = value;
},
/// <summary>
/// Occurs when the file upload starts
/// </summary>
@@ -1570,8 +1786,11 @@ Sys.Extended.UI.AjaxFileUpload.Control.prototype = {
eh(this, e);
}
this._processor.resetUI();
this._canceled = false;
this._isUploading = false;
this._isUploaded = true;
this.enableControls(true);
},