-
-
Resumable.js
-
It's a JavaScript library providing multiple simultaneous, stable and resumable uploads via the HTML5 File API.
-
-
The library is designed to introduce fault-tolerance into the upload of large files through HTTP. This is done by splitting each files into small chunks; whenever the upload of a chunk fails, uploading is retried until the procedure completes. This allows uploads to automatically resume uploading after a network connection is lost either locally or to the server. Additionally, it allows for users to pause and resume uploads without loosing state.
-
-
Resumable.js relies on the HTML5 File API and the ability to chunks files into smaller pieces. Currently, this means that support is limited to Firefox 4+ and Chrome 11+.
-
-
-
-
Demo
-
-
-
-
-
-
-
-
-
-
- |
- |
-
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/java/web/pause.png b/samples/java/web/pause.png
deleted file mode 100644
index 53eada6f..00000000
Binary files a/samples/java/web/pause.png and /dev/null differ
diff --git a/samples/java/web/resumable.js b/samples/java/web/resumable.js
deleted file mode 100644
index 7d7d1863..00000000
--- a/samples/java/web/resumable.js
+++ /dev/null
@@ -1,799 +0,0 @@
-// Generated by CoffeeScript 1.6.1
-(function() {
- var Resumable, ResumableChunk, ResumableFile,
- __slice = [].slice,
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
-
- window.Resumable = Resumable = (function() {
-
- function Resumable(opt) {
- this.opt = opt;
- console.log('constructor');
- this.support = (typeof File !== "undefined" && File !== null) && (typeof Blob !== "undefined" && Blob !== null) && (typeof FileList !== "undefined" && FileList !== null) && ((Blob.prototype.webkitSlice != null) || (Blob.prototype.mozSlice != null) || (Blob.prototype.slice != null));
- this.files = [];
- this.defaults = {
- chunkSize: 1 * 1024 * 1024,
- forceChunkSize: false,
- simultaneousUploads: 3,
- fileParameterName: 'file',
- throttleProgressCallbacks: 0.5,
- query: {},
- headers: {},
- preprocess: null,
- method: 'multipart',
- prioritizeFirstAndLastChunk: false,
- target: '/',
- testChunks: true,
- generateUniqueIdentifier: null,
- maxChunkRetries: void 0,
- chunkRetryInterval: void 0,
- permanentErrors: [415, 500, 501],
- maxFiles: void 0,
- maxFilesErrorCallback: function(files, errorCount) {
- var maxFiles, _ref;
- maxFiles = this.getOpt('maxFiles');
- return alert('Please upload ' + maxFiles + ' file' + ((_ref = maxFiles === 1) != null ? _ref : {
- '': 's'
- }) + ' at a time.');
- },
- minFileSize: void 0,
- minFileSizeErrorCallback: function(file, errorCount) {
- return alert(file.fileName(+' is too small, please upload files larger than ' + this.formatSize(this.getOpt('minFileSize')) + '.'));
- },
- maxFileSize: void 0,
- maxFileSizeErrorCallback: function(file, errorCount) {
- return alert(file.fileName(+' is too large, please upload files less than ' + this.formatSize(this.getOpt('maxFileSize')) + '.'));
- }
- };
- if (this.opt == null) {
- this.opt = {};
- }
- this.events = [];
- }
-
- Resumable.prototype.getOpt = function(o) {
- var item, opts, _i, _len;
- if (o instanceof Array) {
- opts = {};
- for (_i = 0, _len = o.length; _i < _len; _i++) {
- item = o[_i];
- opts[item] = this.getOpt(item);
- }
- return opts;
- } else {
- if (this.opt[o] != null) {
- return this.opt[o];
- } else {
- return this.defaults[o];
- }
- }
- };
-
- Resumable.prototype.formatSize = function(size) {
- if (size < 1024) {
- return size + ' bytes';
- } else if (size < 1024 * 1024) {
- return (size / 1024.0).toFixed(0) + ' KB';
- } else if (size < 1024 * 1024 * 1024) {
- return (size / 1024.0 / 1024.0).toFixed(1) + ' MB';
- } else {
- return (size / 1024.0 / 1024.0 / 1024.0).toFixed(1) + ' GB';
- }
- };
-
- Resumable.prototype.stopEvent = function(e) {
- console.log('stopEvent');
- e.stopPropagation();
- return e.preventDefault();
- };
-
- Resumable.prototype.generateUniqueIdentifier = function(file) {
- var custom, relativePath, size;
- console.log('generateUniqueIdentifier');
- custom = this.getOpt('generateUniqueIdentifier');
- if (typeof custom === 'function') {
- return custom(file);
- } else {
- relativePath = file.webkitRelativePath || file.fileName || file.name;
- size = file.size;
- return size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, '');
- }
- };
-
- Resumable.prototype.on = function(event, callback) {
- console.log("on: " + event);
- return this.events.push({
- event: event,
- callback: callback
- });
- };
-
- Resumable.prototype.fire = function() {
- var args, e, event, _i, _len, _ref;
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
- console.log("fire: " + args[0]);
- event = args[0].toLowerCase();
- _ref = this.events;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- e = _ref[_i];
- if (e.event.toLowerCase() === event) {
- e.callback.apply(this, args.slice(1));
- }
- if (e.event.toLowerCase() === 'catchall') {
- e.callback.apply(null, args);
- }
- }
- if (event === 'fireerror') {
- this.fire('error', args[2], args[1]);
- }
- if (event === 'fileprogress') {
- return this.fire('progress');
- }
- };
-
- Resumable.prototype.onDrop = function(event) {
- console.log("onDrop");
- this.stopEvent(event);
- return this.appendFilesFromFileList(event.dataTransfer.files, event);
- };
-
- Resumable.prototype.onDragOver = function(event) {
- console.log("onDragOver");
- return event.preventDefault();
- };
-
- Resumable.prototype.appendFilesFromFileList = function(fileList, event) {
- var errorCount, file, files, maxFileSize, maxFileSizeErrorCallback, maxFiles, maxFilesErrorCallback, minFileSize, minFileSizeErrorCallback, resumableFile, _i, _len, _ref;
- console.log("appendFilesFromFileList");
- errorCount = 0;
- _ref = this.getOpt(['maxFiles', 'minFileSize', 'maxFileSize', 'maxFilesErrorCallback', 'minFileSizeErrorCallback', 'maxFileSizeErrorCallback']), maxFiles = _ref[0], minFileSize = _ref[1], maxFileSize = _ref[2], maxFilesErrorCallback = _ref[3], minFileSizeErrorCallback = _ref[4], maxFileSizeErrorCallback = _ref[5];
- if ((maxFiles != null) && maxFiles < (fileList.length + this.files.length)) {
- maxFilesErrorCallback(fileList, errorCount++);
- return false;
- }
- files = [];
- for (_i = 0, _len = fileList.length; _i < _len; _i++) {
- file = fileList[_i];
- file.name = file.fileName = file.name || file.fileName;
- if ((minFileSize != null) && file.size < minFileSize) {
- minFileSizeErrorCallback(file, errorCount++);
- return false;
- }
- if ((maxFileSize != null) && file.size > maxFileSize) {
- maxFilesErrorCallback(file, errorCount++);
- return false;
- }
- if (file.size > 0 && !this.getFromUniqueIdentifier(this.generateUniqueIdentifier(file))) {
- resumableFile = new ResumableFile(this, file);
- this.files.push(resumableFile);
- files.push(resumableFile);
- this.fire('fileAdded', resumableFile, event);
- }
- }
- return this.fire('fileAdded', files);
- };
-
- Resumable.prototype.uploadNextChunk = function() {
- var chunk, file, found, outstanding, status, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4;
- console.log("uploadNextChunk");
- found = false;
- if (this.getOpt('prioritizeFirstAndLastChunk')) {
- _ref = this.files;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- file = _ref[_i];
- if (file.chunks.length && file.chunks[0].status() === 'pending' && file.chunks[0].preprocessState === 0) {
- file.chunks[0].send();
- found = true;
- break;
- }
- if (file.chunks.length > 1 && file.chunks[file.chunks.length - 1].status() === 'pending' && file.chunks[file.chunks.length - 1].preprocessState === 0) {
- file.chunks[file.chunks.length - 1].send();
- found = true;
- break;
- }
- }
- if (found) {
- return true;
- }
- }
- _ref1 = this.files;
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
- file = _ref1[_j];
- _ref2 = file.chunks;
- for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
- chunk = _ref2[_k];
- if (chunk.status() === 'pending' && chunk.preprocessState === 0) {
- chunk.send();
- found = true;
- break;
- }
- }
- if (found) {
- break;
- }
- }
- if (found) {
- return true;
- }
- _ref3 = this.files;
- for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
- file = _ref3[_l];
- outstanding = false;
- _ref4 = file.chunks;
- for (_m = 0, _len4 = _ref4.length; _m < _len4; _m++) {
- chunk = _ref4[_m];
- status = chunk.status();
- if (status === 'pending' || status === 'uploading' || chunk.preprocessState === 1) {
- outstanding = true;
- break;
- }
- }
- if (outstanding) {
- break;
- }
- }
- if (!outstanding) {
- this.fire('complete');
- }
- return false;
- };
-
- Resumable.prototype.assignBrowse = function(domNodes, isDirectory) {
- var changeHandler, dn, input, maxFiles, _i, _len,
- _this = this;
- console.log("assignBrowse");
- if (domNodes.length == null) {
- domNodes = [domNodes];
- }
- for (_i = 0, _len = domNodes.length; _i < _len; _i++) {
- dn = domNodes[_i];
- if (dn.tagName === 'INPUT' && dn.type === 'file') {
- input = dn;
- } else {
- input = document.createElement('input');
- input.setAttribute('type', 'file');
- dn.style.display = 'inline-block';
- dn.style.position = 'relative';
- input.style.position = 'absolute';
- input.style.top = input.style.left = input.style.bottom = input.style.right = 0;
- input.style.opacity = 0;
- input.style.cursor = 'pointer';
- dn.appendChild(input);
- }
- }
- maxFiles = this.getOpt('maxFiles');
- if ((maxFiles != null) || maxFiles !== 1) {
- input.setAttribute('multiple', 'multiple');
- } else {
- input.removeAttribute('multiple');
- }
- if (isDirectory) {
- input.setAttribute('webkitdirectory', 'webkitdirectory');
- } else {
- input.removeAttribute('webkitdirectory');
- }
- changeHandler = function(e) {
- _this.appendFilesFromFileList(e.target.files);
- return e.target.value = '';
- };
- return input.addEventListener('change', changeHandler, false);
- };
-
- Resumable.prototype.assignDrop = function(domNodes) {
- var dn, _i, _len, _results;
- console.log("assignDrop");
- if (domNodes.length == null) {
- domNodes = [domNodes];
- }
- _results = [];
- for (_i = 0, _len = domNodes.length; _i < _len; _i++) {
- dn = domNodes[_i];
- dn.addEventListener('dragover', this.onDragOver, false);
- _results.push(dn.addEventListener('drop', this.onDrop, false));
- }
- return _results;
- };
-
- Resumable.prototype.unAssignDrop = function(domNodes) {
- var dn, _i, _len, _results;
- console.log("unAssignDrop");
- if (domNodes.length == null) {
- domNodes = [domNodes];
- }
- _results = [];
- for (_i = 0, _len = domNodes.length; _i < _len; _i++) {
- dn = domNodes[_i];
- dn.removeEventListener('dragover', this.onDragOver);
- _results.push(dn.removeEventListener('drop', this.onDrop));
- }
- return _results;
- };
-
- Resumable.prototype.isUploading = function() {
- var chunk, file, uploading, _i, _j, _len, _len1, _ref, _ref1;
- uploading = false;
- _ref = this.files;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- file = _ref[_i];
- _ref1 = file.chunks;
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
- chunk = _ref1[_j];
- if (chunk.status() === 'uploading') {
- uploading = true;
- break;
- }
- }
- if (uploading) {
- break;
- }
- }
- return uploading;
- };
-
- Resumable.prototype.upload = function() {
- var num, _i, _ref, _results;
- console.log("upload");
- if (this.isUploading()) {
- return;
- }
- this.fire('uploadStart');
- _results = [];
- for (num = _i = 0, _ref = this.getOpt('simultaneousUploads'); 0 <= _ref ? _i <= _ref : _i >= _ref; num = 0 <= _ref ? ++_i : --_i) {
- _results.push(this.uploadNextChunk());
- }
- return _results;
- };
-
- Resumable.prototype.pause = function() {
- var file, _i, _len, _ref;
- console.log("pause");
- _ref = this.files;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- file = _ref[_i];
- file.abort();
- }
- return this.fire('pause');
- };
-
- Resumable.prototype.cancel = function() {
- var file, _i, _len, _ref;
- console.log("cancel");
- _ref = this.files;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- file = _ref[_i];
- file.cancel();
- }
- return this.fire('cancel');
- };
-
- Resumable.prototype.progress = function() {
- var file, totalDone, totalSize, _i, _len, _ref;
- console.log("progress");
- totalDone = 0;
- totalSize = 0;
- _ref = this.files;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- file = _ref[_i];
- totalDone += file.progress() * file.size;
- totalSize += file.size;
- }
- return (totalSize > 0 ? totalDone / totalSize : 0);
- };
-
- Resumable.prototype.addFile = function(file) {
- console.log("addFile");
- return this.appendFilesFromFileList([file]);
- };
-
- Resumable.prototype.removeFile = function(file) {
- var f, files, _i, _len, _ref;
- console.log("removeFile");
- files = [];
- _ref = this.files;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- f = _ref[_i];
- if (f !== file) {
- files.push(f);
- }
- }
- return this.files = files;
- };
-
- Resumable.prototype.getFromUniqueIdentifier = function(uniqueIdentifier) {
- var f, _i, _len, _ref;
- console.log("getFromUniqueIdentifier");
- _ref = this.files;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- f = _ref[_i];
- if (f.uniqueIdentifier === uniqueIdentifier) {
- return f;
- }
- }
- return false;
- };
-
- Resumable.prototype.getSize = function() {
- var file, totalSize, _i, _len, _ref;
- console.log("getSize");
- totalSize = 0;
- _ref = this.files;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- file = _ref[_i];
- totalSize += file.size;
- }
- return totalSize;
- };
-
- return Resumable;
-
- })();
-
- window.ResumableChunk = ResumableChunk = (function() {
-
- function ResumableChunk(resumableObj, fileObj, offset, callback) {
- this.resumableObj = resumableObj;
- this.fileObj = fileObj;
- this.offset = offset;
- this.callback = callback;
- this.opt = {};
- this.fileObjSize = this.fileObj.size;
- this.lastProgressCallback = new Date;
- this.tested = false;
- this.retries = 0;
- this.preprocessState = 0;
- this.chunkSize = this.getOpt('chunkSize');
- this.loaded = 0;
- this.startByte = this.offset * this.chunkSize;
- this.endByte = Math.min(this.fileObjSize, (this.offset + 1) * this.chunkSize);
- if ((this.fileObjSize - this.endByte < this.chunkSize) && (!this.getOpt('forceChunkSize'))) {
- this.endByte = this.fileObjSize;
- }
- this.xhr = null;
- }
-
- ResumableChunk.prototype.getOpt = function(o) {
- return this.resumableObj.getOpt(o);
- };
-
- ResumableChunk.prototype.pushParams = function(params, key, value) {
- return params.push([encodeURIComponent(key), encodeURIComponent(value)].join('='));
- };
-
- ResumableChunk.prototype.test = function() {
- var customQuery, headers, key, params, testHandler, value,
- _this = this;
- this.xhr = new XMLHttpRequest();
- testHandler = function(e) {
- var status;
- _this.tested = true;
- status = _this.status();
- if (status === 'success') {
- _this.callback(status, _this.message());
- return _this.resumableObj.uploadNextChunk();
- } else {
- return _this.send();
- }
- };
- this.xhr.addEventListener('load', testHandler, false);
- this.xhr.addEventListener('error', testHandler, false);
- params = [];
- customQuery = this.getOpt('query');
- if (typeof customQuery === 'function') {
- customQuery = customQuery(this.fileObj, this);
- }
- if (customQuery != null) {
- for (key in customQuery) {
- value = customQuery[key];
- pushParams(key, value);
- }
- }
- this.pushParams(params, 'resumableChunkNumber', this.offset + 1);
- this.pushParams(params, 'resumableChunkSize', this.chunkSize);
- this.pushParams(params, 'resumableCurrentChunkSize', this.endByte - this.startByte);
- this.pushParams(params, 'resumableTotalSize', this.fileObjSize);
- this.pushParams(params, 'resumableIdentifier', this.fileObj.uniqueIdentifier);
- this.pushParams(params, 'resumableFilename', this.fileObj.fileName);
- this.pushParams(params, 'resumableRelativePath', this.fileObj.relativePath);
- this.xhr.open('GET', this.getOpt('target') + '?' + params.join('&'));
- headers = this.getOpt('headers');
- if (headers == null) {
- headers = {};
- }
- for (key in headers) {
- value = headers[key];
- this.xhr.setRequestHeader(key, value);
- }
- return this.xhr.send(null);
- };
-
- ResumableChunk.prototype.preprocessFinished = function() {
- this.preprocessState = 2;
- return this.send();
- };
-
- ResumableChunk.prototype.send = function() {
- var bytes, customQuery, data, doneHandler, func, headers, key, params, preprocess, progressHandler, query, ret, target, value,
- _this = this;
- preprocess = this.getOpt('preprocess');
- if (typeof preprocess === 'function') {
- ret = false;
- switch (this.preprocessState) {
- case 0:
- preprocess(this);
- this.preprocessState = 1;
- ret = true;
- break;
- case 1:
- ret = true;
- break;
- case 2:
- ret = false;
- }
- if (ret) {
- return;
- }
- }
- if (this.getOpt('testChunks') && !this.tested) {
- this.test();
- return;
- }
- this.xhr = new XMLHttpRequest();
- this.loaded = 0;
- progressHandler = function(e) {
- if ((new Date) - _this.lastProgressCallback > _this.getOpt('throttleProgressCallbacks') * 1000) {
- _this.callback('progress');
- _this.lastProgressCallback = new Date;
- }
- return _this.loaded = e.loaded || 0;
- };
- this.xhr.upload.addEventListener('progress', progressHandler, false);
- this.callback('progress');
- doneHandler = function(e) {
- var retryInterval, status;
- status = _this.status();
- if (status === 'success' || status === 'error') {
- _this.callback(status, _this.message());
- return _this.resumableObj.uploadNextChunk();
- } else {
- _this.callback('retry', _this.message());
- _this.abort();
- _this.retries++;
- retryInterval = getOpt('chunkRetryInterval');
- if (retryInterval != null) {
- return setTimeout(_this.send, retryInterval);
- }
- }
- };
- this.xhr.addEventListener('load', doneHandler, false);
- this.xhr.addEventListener('error', doneHandler, false);
- headers = this.getOpt('headers');
- if (headers == null) {
- headers = {};
- }
- for (key in headers) {
- value = headers[key];
- this.xhr.setRequestHeader(key, value);
- }
- if (this.fileObj.file.slice != null) {
- func = 'slice';
- } else if (this.fileObj.file.mozSlice != null) {
- func = 'mozSlice';
- } else if (this.fileObj.file.webkitSlice != null) {
- func = 'webkitSlice';
- } else {
- func = 'slice';
- }
- bytes = this.fileObj.file[func](this.startByte, this.endByte);
- data = null;
- target = this.getOpt('target');
- query = {
- resumableChunkNumber: this.offset + 1,
- resumableChunkSize: this.getOpt('chunkSize'),
- resumableCurrentChunkSize: this.endByte - this.startByte,
- resumableTotalSize: this.fileObjSize,
- resumableIdentifier: this.fileObj.uniqueIdentifier,
- resumableFilename: this.fileObj.fileName,
- resumableRelativePath: this.fileObj.relativePath
- };
- customQuery = this.getOpt('query');
- if (typeof customQuery === 'function') {
- customQuery = customQuery(this.fileObj, this);
- }
- if (customQuery == null) {
- customQuery = {};
- }
- for (key in customQuery) {
- value = customQuery[key];
- pushParams(query, key, value);
- }
- if (this.getOpt('method') === 'octet') {
- data = bytes;
- params = [];
- for (key in query) {
- value = query[key];
- this.pushParams(params, key, value);
- }
- target += '?' + params.join('&');
- } else {
- data = new FormData();
- for (key in query) {
- value = query[key];
- data.append(key, value);
- }
- data.append(this.getOpt('fileParameterName'), bytes);
- }
- this.xhr.open('POST', target);
- return this.xhr.send(data);
- };
-
- ResumableChunk.prototype.abort = function() {
- if (this.xhr != null) {
- this.xhr.abort();
- }
- return this.xhr = null;
- };
-
- ResumableChunk.prototype.status = function() {
- var maxChunkRetries, permanentErrors, _ref;
- permanentErrors = this.getOpt('permanentErrors');
- maxChunkRetries = this.getOpt('maxChunkRetries');
- if (permanentErrors == null) {
- permanentErrors = {};
- }
- if (maxChunkRetries == null) {
- maxChunkRetries = 0;
- }
- if (this.xhr == null) {
- return 'pending';
- } else if (this.xhr.readyState < 4) {
- return 'uploading';
- } else if (this.xhr.status === 200) {
- return 'success';
- } else if ((_ref = this.xhr.status, __indexOf.call(permanentErrors, _ref) >= 0) || (this.retries >= maxChunkRetries)) {
- return 'error';
- } else {
- this.abort();
- return 'pending';
- }
- };
-
- ResumableChunk.prototype.message = function() {
- return (this.xhr != null ? this.xhr.responseText : '');
- };
-
- ResumableChunk.prototype.progress = function(relative) {
- var factor;
- factor = (relative != null ? (this.endByte - this.startByte) / this.fileObjSize : 1);
- switch (this.status()) {
- case 'success':
- case 'error':
- return 1 * factor;
- case 'pending':
- return 0 * factor;
- default:
- return this.loaded / (this.endByte - this.startByte) * factor;
- }
- };
-
- return ResumableChunk;
-
- })();
-
- window.ResumableFile = ResumableFile = (function() {
-
- function ResumableFile(resumableObj, file) {
- this.resumableObj = resumableObj;
- this.file = file;
- this.opt = {};
- this._prevProgress = 0;
- this.fileName = this.file.fileName || this.file.name;
- this.size = this.file.size;
- this.relativePath = this.file.webkitRelativePath || this.fileName;
- this.uniqueIdentifier = this.resumableObj.generateUniqueIdentifier(this.file);
- this._error = false;
- this.chunks = [];
- this.bootstrap();
- }
-
- ResumableFile.prototype.getOpt = function(o) {
- return this.resumableObj.getOpt(o);
- };
-
- ResumableFile.prototype.chunkEvent = function(event, message) {
- switch (event) {
- case "progress":
- return this.resumableObj.fire('fileProgress', this);
- case "error":
- this.abort();
- this._error = true;
- this.chunks = [];
- return this.resumableObj.fire('fileError', this, message);
- case "success":
- if (!this._error) {
- this.resumableObj.fire('fileProgress', this);
- if (this.progress() === 1) {
- return this.resumableObj.fire('fileSuccess', this, message);
- }
- }
- break;
- case "retry":
- return this.resumableObj.fire('fileRetry', this);
- }
- };
-
- ResumableFile.prototype.abort = function() {
- var c, _i, _len, _ref;
- _ref = this.chunks;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- c = _ref[_i];
- if (c.status() === 'uploading') {
- c.abort();
- }
- }
- return this.resumableObj.fire('fileProgress', this);
- };
-
- ResumableFile.prototype.cancel = function() {
- var c, _chunks, _i, _len;
- _chunks = this.chunks;
- this.chunks = [];
- for (_i = 0, _len = _chunks.length; _i < _len; _i++) {
- c = _chunks[_i];
- if (c.status() === 'uploading') {
- c.abort();
- this.resumableObj.uploadNextChunk();
- }
- }
- this.resumableObj.removeFile(this);
- return this.resumableObj.fire('fileProgress', this);
- };
-
- ResumableFile.prototype.retry = function() {
- this.bootstrap();
- return this.resumableObj.upload();
- };
-
- ResumableFile.prototype.bootstrap = function() {
- var max, offset, round, _i, _ref, _results;
- this.abort();
- this._error = false;
- this.chunks = [];
- this._prevProgress = 0;
- if (this.getOpt('forceChunkSize') != null) {
- round = Math.ceil;
- } else {
- round = Math.floor;
- }
- offset = 0;
- max = Math.max(round(this.file.size / this.getOpt('chunkSize')), 1);
- _results = [];
- for (offset = _i = 0, _ref = max - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; offset = 0 <= _ref ? ++_i : --_i) {
- _results.push(this.chunks.push(new ResumableChunk(this.resumableObj, this, offset, this.chunkEvent)));
- }
- return _results;
- };
-
- ResumableFile.prototype.progress = function() {
- var c, error, ret, _i, _len, _ref;
- if (this._error) {
- return 1.;
- }
- ret = 0;
- error = false;
- _ref = this.chunks;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- c = _ref[_i];
- error = c.status() === 'error';
- ret += c.progress(true);
- }
- ret = (error || error > 0.99 ? 1 : ret);
- ret = Math.max(this._prevProgress, ret);
- this._prevProgress = ret;
- return ret;
- };
-
- return ResumableFile;
-
- })();
-
-}).call(this);
diff --git a/samples/java/web/resume.png b/samples/java/web/resume.png
deleted file mode 100644
index b150936d..00000000
Binary files a/samples/java/web/resume.png and /dev/null differ
diff --git a/samples/java/web/style.css b/samples/java/web/style.css
deleted file mode 100644
index 026656fc..00000000
--- a/samples/java/web/style.css
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Reset */
-body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,th,var{font-style:normal;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;}
-
-/* Baseline */
-body, p, h1, h2, h3, h4, h5, h6 {font:normal 12px/1.3em Helvetica, Arial, sans-serif; color:#333; }
-h1 {font-size:22px; font-weight:bold;}
-h2 {font-size:19px; font-weight:bold;}
-h3 {font-size:16px; font-weight:bold;}
-h4 {font-size:14px; font-weight:bold;}
-h5 {font-size:12px; font-weight:bold;}
-p {margin:10px 0;}
-
-
-body {text-align:center; margin:40px;}
-#frame {margin:0 auto; width:800px; text-align:left;}
-
-
-
-/* Uploader: Drag & Drop */
-.resumable-error {display:none; font-size:14px; font-style:italic;}
-.resumable-drop {padding:15px; font-size:13px; text-align:center; color:#666; font-weight:bold;background-color:#eee; border:2px dashed #aaa; border-radius:10px; margin-top:40px; z-index:9999; display:none;}
-.resumable-dragover {padding:30px; color:#555; background-color:#ddd; border:1px solid #999;}
-
-/* Uploader: Progress bar */
-.resumable-progress {margin:30px 0 30px 0; width:100%; display:none;}
-.progress-container {height:7px; background:#9CBD94; position:relative; }
-.progress-bar {position:absolute; top:0; left:0; bottom:0; background:#45913A; width:0;}
-.progress-text {font-size:11px; line-height:9px; padding-left:10px;}
-.progress-pause {padding:0 0 0 7px;}
-.progress-resume-link {display:none;}
-.is-paused .progress-resume-link {display:inline;}
-.is-paused .progress-pause-link {display:none;}
-.is-complete .progress-pause {display:none;}
-
-/* Uploader: List of items being uploaded */
-.resumable-list {overflow:auto; margin-right:-20px; display:none;}
-.uploader-item {width:148px; height:90px; background-color:#666; position:relative; border:2px solid black; float:left; margin:0 6px 6px 0;}
-.uploader-item-thumbnail {width:100%; height:100%; position:absolute; top:0; left:0;}
-.uploader-item img.uploader-item-thumbnail {opacity:0;}
-.uploader-item-creating-thumbnail {padding:0 5px; font-size:9px; color:white;}
-.uploader-item-title {position:absolute; font-size:9px; line-height:11px; padding:3px 50px 3px 5px; bottom:0; left:0; right:0; color:white; background-color:rgba(0,0,0,0.6); min-height:27px;}
-.uploader-item-status {position:absolute; bottom:3px; right:3px;}
-
-/* Uploader: Hover & Active status */
-.uploader-item:hover, .is-active .uploader-item {border-color:#4a873c; cursor:pointer; }
-.uploader-item:hover .uploader-item-title, .is-active .uploader-item .uploader-item-title {background-color:rgba(74,135,60,0.8);}
-
-/* Uploader: Error status */
-.is-error .uploader-item:hover, .is-active.is-error .uploader-item {border-color:#900;}
-.is-error .uploader-item:hover .uploader-item-title, .is-active.is-error .uploader-item .uploader-item-title {background-color:rgba(153,0,0,0.6);}
-.is-error .uploader-item-creating-thumbnail {display:none;}
\ No newline at end of file
diff --git a/src/api.js b/src/api.js
new file mode 100644
index 00000000..67d66219
--- /dev/null
+++ b/src/api.js
@@ -0,0 +1,4 @@
+extend(flow, {
+ 'extend': extend,
+ 'each': each
+});
\ No newline at end of file
diff --git a/src/export.js b/src/export.js
new file mode 100644
index 00000000..5d1dd799
--- /dev/null
+++ b/src/export.js
@@ -0,0 +1,20 @@
+if (typeof module === 'object' && module && typeof module.exports === 'object') {
+ // Expose Flow as module.exports in loaders that implement the Node
+ // module pattern (including browserify). Do not create the global, since
+ // the user will be storing it themselves locally, and globals are frowned
+ // upon in the Node module world.
+ module.exports = flow;
+} else {
+ // Otherwise expose Flow to the global object as usual
+ window.flow = flow;
+
+ // Register as a named AMD module, since Flow can be concatenated with other
+ // files that may use define, but not via a proper concatenation script that
+ // understands anonymous AMD modules. A named AMD is safest and most robust
+ // way to register. Lowercase flow is used because AMD module names are
+ // derived from file names, and Flow is normally delivered in a lowercase
+ // file name.
+ if (typeof define === 'function' && define.amd) {
+ define('flow', [], function () { return flow; });
+ }
+}
\ No newline at end of file
diff --git a/src/flow.js b/src/flow.js
index aceab424..42839359 100644
--- a/src/flow.js
+++ b/src/flow.js
@@ -1,1675 +1,209 @@
/**
- * @license MIT
+ * File uploader
+ * @function
+ * @param {Object} [opts]
*/
-(function(window, document, undefined) {'use strict';
- if (!window || !document) {
- console.warn('Flowjs needs window and document objects to work');
- return;
- }
- // ie10+
- var ie10plus = window.navigator.msPointerEnabled;
- /**
- * Flow.js is a library providing multiple simultaneous, stable and
- * resumable uploads via the HTML5 File API.
- * @param [opts]
- * @param {number|Function} [opts.chunkSize]
- * @param {bool} [opts.forceChunkSize]
- * @param {number} [opts.simultaneousUploads]
- * @param {bool} [opts.singleFile]
- * @param {string} [opts.fileParameterName]
- * @param {number} [opts.progressCallbacksInterval]
- * @param {number} [opts.speedSmoothingFactor]
- * @param {Object|Function} [opts.query]
- * @param {Object|Function} [opts.headers]
- * @param {bool} [opts.withCredentials]
- * @param {Function} [opts.preprocess]
- * @param {string} [opts.method]
- * @param {string|Function} [opts.testMethod]
- * @param {string|Function} [opts.uploadMethod]
- * @param {bool} [opts.prioritizeFirstAndLastChunk]
- * @param {bool} [opts.allowDuplicateUploads]
- * @param {string|Function} [opts.target]
- * @param {number} [opts.maxChunkRetries]
- * @param {number} [opts.chunkRetryInterval]
- * @param {Array.