c9-core/plugins/c9.ide.upload/upload_job.js

124 wiersze
3.2 KiB
JavaScript

define(function(require, module, exports) {
"use strict";
var EventEmitter = require("events").EventEmitter;
var path = require("path");
var STATE_NEW = "new";
var STATE_UPLOADING = "uploading";
var STATE_PAUSED = "paused";
var STATE_RESUME = "resume";
var STATE_DONE = "done";
var STATE_ERROR = "error";
function UploadJob(file, fullPath, manager, workerPrefix) {
this.fullPath = fullPath;
this.file = file;
this.manager = manager;
this.state = STATE_NEW;
this.progress = 0;
this.id = UploadJob.ID++;
this.workerPrefix = workerPrefix;
var emitter = new EventEmitter();
this.on = emitter.on.bind(emitter);
this.off = emitter.off.bind(emitter);
this._emit = emitter.emit.bind(emitter);
}
UploadJob.ID = 1;
UploadJob.prototype.cancel = function() {
if (this.xhr)
this.xhr.abort();
this._setState(STATE_ERROR);
};
UploadJob.prototype._setState = function(state) {
this.state = state;
this._emit("changeState", { state: state, job: this });
};
UploadJob.prototype._error = function(code, message) {
this.error = {
code: code,
message: message
};
this._setState(STATE_ERROR);
};
UploadJob.prototype._progress = function(progress) {
this.progress = progress;
this._emit("progress", { progress: progress, job: this });
};
UploadJob.prototype._startUpload = function() {
var job = this;
job._setState(STATE_UPLOADING);
if (job.vfs) {
return job.vfs.rest(job.fullPath, {
method: "PUT",
body: job.file,
timeout: 0,
progress: function(loaded, total) {
job._progress(loaded / total);
}
}, function(err, data, res) {
job._progress(1);
if (err)
job._error(err.status, err.message);
else
job._setState("done");
});
} else {
var url = path.join(job.manager.filesPrefix, job.fullPath);
var xhr = new XMLHttpRequest();
xhr.open("PUT", url, true);
xhr.onload = function(e) {
job._progress(1);
if (xhr.status >= 400)
job._error(xhr.status, xhr.statusText);
else
job._setState("done");
xhr = null;
};
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
job._progress(e.loaded / e.total);
}
};
xhr.send(job.file);
}
};
UploadJob.prototype._startUploadWorker = function() {
var job = this;
job._setState(STATE_UPLOADING);
var url = path.join(job.manager.filesPrefix, job.fullPath);
var worker = new Worker(path.join(this.workerPrefix, "upload_worker.js"));
worker.postMessage({ method: "start", args: [job.file, url]});
this.xhr = {
abort: worker.postMessage.bind(worker, { method: "abort" })
};
worker.onmessage = function(msg) {
var method = msg.data.method;
var args = msg.data.args || [];
if (method == "_setState") {
this.xhr = null;
worker.terminate();
}
job[method].apply(job, args);
};
};
return UploadJob;
});