Files
2026-09-15 10:26:34 +08:00

118 lines
3.7 KiB
JavaScript
Executable File

(function (factory) {
// Module systems magic dance.
if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
// CommonJS or Node: hard-coded dependency on "knockout"
factory(require("knockout"));
} else if (typeof define === "function" && define["amd"]) {
// AMD anonymous module with hard-coded dependency on "knockout"
define(["knockout"], factory);
} else {
// <script> tag: use the global `ko` object, attaching a `mapping` property
factory(ko);
}
}
(function (ko) {
ko.bindingHandlers.files = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var allBindings = allBindingsAccessor();
var loadedCallback, progressCallback, errorCallback, hoverClass, allowDrop, fileFilter, readAs, maxFileSize;
var filesBinding = allBindings.files;
if (typeof(ko.unwrap(filesBinding)) == "function")
{ loadedCallback = ko.unwrap(filesBinding); }
else
{
loadedCallback = ko.unwrap(filesBinding.onLoaded);
progressCallback = ko.unwrap(filesBinding.onProgress);
errorCallback = ko.unwrap(filesBinding.onError);
allowDrop = ko.unwrap(filesBinding.allowDrop);
hoverClass = ko.unwrap(filesBinding.hoverClass);
fileFilter = ko.unwrap(filesBinding.fileFilter);
maxFileSize = ko.unwrap(filesBinding.maxFileSize);
readAs = ko.unwrap(filesBinding.readAs);
}
if(typeof(loadedCallback) != "function")
{ return; }
var readFile = function(file) {
var reader = new FileReader();
reader.onload = function(fileLoadedEvent) {
loadedCallback(file, fileLoadedEvent.target.result);
};
if(typeof(progressCallback) == "function")
{
reader.onprogress = function(fileProgressEvent) {
progressCallback(file, fileProgressEvent.loaded, fileProgressEvent.total);
};
}
if(typeof(errorCallback) == "function")
{
reader.onerror = function(fileErrorEvent) {
errorCallback(file, fileErrorEvent.target.error);
};
}
if(readAs == "text")
{ reader.readAsText(file); }
else if(readAs == "array")
{ reader.readAsArrayBuffer(file); }
else if(readAs == "binary")
{ reader.readAsBinaryString(file); }
else
{ reader.readAsDataURL(file); }
};
var handleFileDrag = function(fileDragEvent) {
fileDragEvent.stopPropagation();
fileDragEvent.preventDefault();
if(fileDragEvent.type == "dragover")
{ fileDragEvent.target.classList.add(hoverClass); }
else
{ fileDragEvent.target.classList.remove(hoverClass); }
};
var handleDrop = function(fileDropEvent) {
handleFileDrag(fileDropEvent);
handleFileSelected(fileDropEvent);
}
var handleFileSelected = function(fileSelectionEvent) {
var files = fileSelectionEvent.target.files || fileSelectionEvent.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
if (typeof(fileFilter) != "undefined" && !f.type.match(fileFilter))
{
if(typeof(errorCallback) == "function")
{ errorCallback(f, "File type does not match filter"); }
continue;
}
if(typeof(maxFileSize) != "undefined" && f.size >= maxFileSize)
{
if(typeof(errorCallback) == "function")
{ errorCallback(f, "File exceeds file size limit"); }
continue;
}
readFile(f);
}
};
if (!document.addEventListener) {
return; //IE8 won't work with addEventListener, avoid JS error
}
element.addEventListener('change', handleFileSelected, false);
if(allowDrop) {
element.addEventListener('dragover', handleFileDrag, false);
element.addEventListener('dragleave', handleFileDrag, false);
element.addEventListener('drop', handleDrop, false);
}
}
};
}));