summaryrefslogtreecommitdiff
path: root/js/cheesesteak.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/cheesesteak.js')
-rw-r--r--js/cheesesteak.js174
1 files changed, 98 insertions, 76 deletions
diff --git a/js/cheesesteak.js b/js/cheesesteak.js
index ea3dc19..6e20880 100644
--- a/js/cheesesteak.js
+++ b/js/cheesesteak.js
@@ -20,10 +20,54 @@
* SOFTWARE.
*/
-/* jshint browser:true, jquery:true */
(function() {
// Lightweight EventEmitter implementation
- EventEmitter = function() {};
+ var EventEmitter = function() {};
+
+ // Utility to convert bytes into human units
+ var humanSize = {
+ get: function humanSize() {
+ var units = [
+ 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB',
+ ];
+ var base = Math.floor(Math.log(this.size) / Math.log(1024));
+ return (this.size / Math.pow(1024, base)).toFixed(2) + ' ' + units[base];
+ },
+ };
+
+ var percentUploaded = {
+ get: function percentUploaded() {
+ return this.uploadedSize / this.size;
+ },
+ };
+
+ // b gets merged as defaults for a
+ var merge = function merge(base, overlay) {
+ var out = base;
+ var key;
+
+ for (key in overlay) {
+ if (typeof overlay[key] === 'object') {
+ out[key] = merge(base[key], overlay[key]);
+ } else {
+ out[key] = overlay[key];
+ }
+ }
+
+ return out;
+ };
+
+ var FileListUploader = function(url, files, opts) {
+ var request = opts || {};
+
+ this.url = url;
+ this.files = files;
+ this.opts = merge({
+ field: 'files[]',
+ method: 'POST',
+ data: {},
+ }, request);
+ };
EventEmitter.prototype.on = function(evt, fn) {
this._events = this._events || {};
@@ -40,11 +84,18 @@
};
EventEmitter.prototype.emit = function(evt) {
+ var i;
+ var len;
+
+ // Check whether the event we want to emit actually exists
if (!this.hasOwnProperty('_events') || evt in this._events === false) {
return;
}
- for (var i = 0, l = this._events[evt].length; i < l; i++) {
+ len = this._events[evt].length;
+
+ // Call all functions that are bound to the event
+ for (i = 0; i < len; i++) {
this._events[evt][i].apply(this, Array.prototype.slice.call(arguments,
1));
}
@@ -64,27 +115,12 @@
return this.reduce(function(prev, curr) {
return prev + curr.size;
}, 0);
- }
+ },
});
- // Utility to convert bytes into human units
- var humanSize = {
- get: function humanSize() {
- var units = [
- 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'
- ];
- var e = Math.floor(Math.log(this.size) / Math.log(1024));
- return (this.size / Math.pow(1024, e)).toFixed(2) + ' ' + units[e];
- }
- };
Object.defineProperty(FileList.prototype, 'humanSize', humanSize);
Object.defineProperty(File.prototype, 'humanSize', humanSize);
- var percentUploaded = {
- get: function percentUploaded() {
- return this.uploadedSize / this.size;
- }
- };
Object.defineProperty(FileList.prototype, 'percentUploaded',
percentUploaded);
Object.defineProperty(File.prototype, 'percentUploaded', percentUploaded);
@@ -94,73 +130,52 @@
return this.reduce(function(prev, curr) {
return prev + (curr.uploadedSize || 0);
}, 0);
- }
+ },
});
// Object URL stuff
Object.defineProperty(File.prototype, 'url', {
get: function getURL() {
return window.URL.createObjectURL(this);
- }
+ },
});
File.revokeURL = function revokeURL(url) {
window.URL.revokeObjectURL(url);
};
- // b gets merged as defaults for a
- var merge = function merge(base, overlay) {
- var out = base;
- for (var key in overlay) {
- if (typeof overlay[key] === 'object') {
- out[key] = merge(base[key], overlay[key]);
- } else {
- out[key] = overlay[key];
- }
- }
-
- return out;
- };
-
- var FileListUploader = function(url, files, opts) {
- this.url = url;
- this.files = files;
-
- opts = opts || {};
-
- this.opts = merge({
- field: 'files[]',
- method: 'POST',
- data: {}
- }, opts);
- };
-
FileListUploader.prototype = Object.create(EventEmitter.prototype);
FileListUploader.prototype.upload = function(cb) {
- if (cb) {
- this.on('uploadcomplete', cb);
- }
-
var opts = this.opts;
var files = this.files;
var _this = this;
-
+ var len = files.length;
var data = new FormData();
+ var xhr = new XMLHttpRequest();
+ var i;
+
+ if (cb) {
+ this.on('uploadcomplete', cb);
+ }
+
files.forEach(function(file) {
data.append(opts.field, file);
});
- var xhr = new XMLHttpRequest();
-
xhr.open(opts.method, this.url, true);
- xhr.upload.addEventListener('loadstart', function(e) {
- for (var i = 0, l = files.length; i < l; i++) {
+
+ function initProgressBar() {
+ for (i = 0; i < len; i++) {
files[i].uploadedSize = 0;
}
- });
+ }
- xhr.upload.addEventListener('progress', function(e) {
- if (e.lengthComputable) {
- size = e.loaded;
+ xhr.upload.addEventListener('loadstart', initProgressBar);
+
+ function updateProgressBar(evt) {
+ var size;
+
+ if (evt.lengthComputable) {
+ size = evt.loaded;
/**
* We know the size of the files, the order they're in, and how
@@ -170,7 +185,7 @@
*/
// TODO: This math has trouble on later uploads. Leak somewhere.
- for (var i = 0, l = files.length; i < l; i++) {
+ for (i = 0; i < len; i++) {
files[i].uploadedSize = Math.min(size, files[i].size);
size -= files[i].uploadedSize;
if (size <= 0) {
@@ -180,24 +195,31 @@
}
}
- _this.emit('uploadprogress', e, files);
- }, false);
+ _this.emit('uploadprogress', evt, files);
+ }
- xhr.upload.addEventListener('loadstart', function(e) {
- _this.emit('uploadstart', e);
- });
+ xhr.upload.addEventListener('progress', updateProgressBar, false);
- xhr.upload.addEventListener('load', function(e) {
- _this.emit('uploadcomplete', e);
- });
+ // The upload is complete, now tell the user to wait for URLs.
+ function postUpload(evt) {
+ _this.emit('uploadcomplete', evt);
+ }
- xhr.addEventListener('progress', function(e) {
- _this.emit('progress', e);
- });
+ xhr.upload.addEventListener('load', postUpload);
- xhr.addEventListener('load', function(e) {
- _this.emit('load', e, xhr.responseText);
- });
+ // Tell the browser the upload completed and wait for response.
+ function postProgress(evt) {
+ _this.emit('progress', evt);
+ }
+
+ xhr.addEventListener('progress', postProgress);
+
+ // Send a success/error response. Nothing more to do.
+ function uploadFinished(evt) {
+ _this.emit('load', evt, xhr.responseText);
+ }
+
+ xhr.addEventListener('load', uploadFinished);
xhr.send(data);