Skip to content

Commit

Permalink
Merge remote branch 'colin/FLUID-4256'
Browse files Browse the repository at this point in the history
* colin/FLUID-4256:
  FLUID-4256: Refactored the various doUpload() implementations into components, simplifying them quite a bit.
  FLUID-4256: Rename FormData creator
  FLUID-4256: Add an expander for the FormData parameter in the FormData Upload
  • Loading branch information
jobara committed May 27, 2011
2 parents 6ec70e2 + 98150d4 commit b62f829
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 69 deletions.
148 changes: 86 additions & 62 deletions src/webapp/components/uploader/js/HTML5UploaderSupport.js
Expand Up @@ -104,11 +104,6 @@ var fluid_1_4 = fluid_1_4 || {};
return that;
};

fluid.uploader.html5Strategy.createFileUploadXHR = function () {
var xhr = new XMLHttpRequest();
return xhr;
};

fluid.uploader.html5Strategy.monitorFileUploadXHR = function (file, events, xhr) {
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
Expand All @@ -128,17 +123,13 @@ var fluid_1_4 = fluid_1_4 || {};
xhr.upload.onprogress = function (pe) {
events.onFileProgress.fire(file, progressTracker.getChunkSize(pe.loaded), pe.total);
};

return xhr;
};

// Set additional POST parameters for xhr
var setPostParams = function (formData, postParams) {
$.each(postParams, function (key, value) {
formData.append(key, value);
});
};

/*************************************
* HTML5 Strategy's remote behaviour *
*************************************/

fluid.uploader.html5Strategy.remote = function (queue, options) {
var that = fluid.initLittleComponent("fluid.uploader.html5Strategy.remote", options);
that.queue = queue;
Expand All @@ -153,10 +144,9 @@ var fluid_1_4 = fluid_1_4 || {};

that.uploadFile = function (file) {
that.events.onFileStart.fire(file);
var xhr = that.createXHR();
var formData = that.createFormData();
that.currentXHR = fluid.uploader.html5Strategy.monitorFileUploadXHR(file, that.events, xhr);
that.doUpload(file, that.queueSettings, that.currentXHR, formData);
that.currentXHR = that.createXHR();
fluid.uploader.html5Strategy.monitorFileUploadXHR(file, that.events, that.currentXHR);
that.fileSender.send(file, that.queueSettings, that.currentXHR);
};

that.stop = function () {
Expand All @@ -174,10 +164,13 @@ var fluid_1_4 = fluid_1_4 || {};
argumentMap: {
options: 1
},
components: {
fileSender: {
type: "fluid.uploader.html5Strategy.fileSender"
}
},
invokers: {
doUpload: "fluid.uploader.html5Strategy.doUpload",
createXHR: "fluid.uploader.html5Strategy.createFileUploadXHR",
createFormData: "fluid.uploader.html5Strategy.createFormData"
createXHR: "fluid.uploader.html5Strategy.createXHR"
}
});

Expand All @@ -188,27 +181,60 @@ var fluid_1_4 = fluid_1_4 || {};
fluid.COMPONENT_OPTIONS
]
});

var CRLF = "\r\n";


fluid.uploader.html5Strategy.createXHR = function () {
return new XMLHttpRequest();
};

fluid.uploader.html5Strategy.createFormData = function () {
var formData = new FormData();
return formData;
return new FormData();
};

/**
* Firefox 4 implementation. FF4 has implemented a FormData function which
* conveniently provides easy construct of set key/value pairs representing
* form fields and their values. The FormData is then easily sent using the
* XMLHttpRequest send() method.
*/
fluid.uploader.html5Strategy.doFormDataUpload = function (file, queueSettings, xhr, formData) {
formData.append("file", file);
setPostParams(formData, queueSettings.postParams);
xhr.open("POST", queueSettings.uploadURL, true);
xhr.send(formData);
// Set additional POST parameters for xhr
var setPostParams = function (formData, postParams) {
$.each(postParams, function (key, value) {
formData.append(key, value);
});
};

/*******************************************************
* HTML5 FormData Sender, used by most modern browsers *
*******************************************************/

fluid.defaults("fluid.uploader.html5Strategy.formDataSender", {
gradeNames: ["fluid.littleComponent", "autoInit"],
finalInitFunction: "fluid.uploader.html5Strategy.formDataSender.init",
invokers: {
createFormData: "fluid.uploader.html5Strategy.createFormData"
}
});

fluid.uploader.html5Strategy.formDataSender.init = function (that) {
/**
* Uploads the file using the HTML5 FormData object.
*/
that.send = function (file, queueSettings, xhr) {
var formData = that.createFormData();
formData.append("file", file);
setPostParams(formData, queueSettings.postParams);
xhr.open("POST", queueSettings.uploadURL, true);
xhr.send(formData);
return formData;
};
};

fluid.demands("fluid.uploader.html5Strategy.fileSender", [
"fluid.uploader.html5Strategy.remote",
"fluid.browser.supportsFormData"
], {
funcName: "fluid.uploader.html5Strategy.formDataSender"
});

/********************************************
* Raw MIME Sender, required by Firefox 3.6 *
********************************************/

fluid.uploader.html5Strategy.generateMultipartBoundary = function () {
var boundary = "---------------------------";
boundary += Math.floor(Math.random() * 32768);
Expand All @@ -218,6 +244,7 @@ var fluid_1_4 = fluid_1_4 || {};
};

fluid.uploader.html5Strategy.generateMultiPartContent = function (boundary, file) {
var CRLF = "\r\n";
var multipart = "";
multipart += "--" + boundary + CRLF;
multipart += "Content-Disposition: form-data;" +
Expand All @@ -230,37 +257,34 @@ var fluid_1_4 = fluid_1_4 || {};
return multipart;
};

/*
* Create the multipart/form-data content by hand to send the file
*/
fluid.uploader.html5Strategy.doManualMultipartUpload = function (file, queueSettings, xhr) {
var boundary = fluid.uploader.html5Strategy.generateMultipartBoundary();
var multipart = fluid.uploader.html5Strategy.generateMultiPartContent(boundary, file);

xhr.open("POST", queueSettings.uploadURL, true);
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
xhr.sendAsBinary(multipart);
};

// Default configuration for older browsers that don't support FormData
fluid.demands("fluid.uploader.html5Strategy.doUpload", "fluid.uploader.html5Strategy.remote", {
funcName: "fluid.uploader.html5Strategy.doManualMultipartUpload",
args: ["@0", "@1", "@2"]
fluid.defaults("fluid.uploader.html5Strategy.rawMIMESender", {
gradeNames: ["fluid.littleComponent", "autoInit"],
finalInitFunction: "fluid.uploader.html5Strategy.rawMIMESender.init"
});

fluid.demands("fluid.uploader.html5Strategy.createFileUploadXHR", "fluid.uploader.html5Strategy.remote", {
funcName: "fluid.uploader.html5Strategy.createFileUploadXHR"
});
fluid.uploader.html5Strategy.rawMIMESender.init = function (that) {
/**
* Uploads the file by manually creating the multipart/form-data request. Required by Firefox 3.6.
*/
that.send = function (file, queueSettings, xhr) {
var boundary = fluid.uploader.html5Strategy.generateMultipartBoundary();
var multipart = fluid.uploader.html5Strategy.generateMultiPartContent(boundary, file);
xhr.open("POST", queueSettings.uploadURL, true);
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
xhr.sendAsBinary(multipart);
return multipart;
};
};

// Configuration for FF4, Chrome, and Safari 4+, all of which support FormData correctly.
fluid.demands("fluid.uploader.html5Strategy.doUpload", [
"fluid.uploader.html5Strategy.remote",
"fluid.browser.supportsFormData"
], {
funcName: "fluid.uploader.html5Strategy.doFormDataUpload",
args: ["@0", "@1", "@2", "@3"]
fluid.demands("fluid.uploader.html5Strategy.fileSender", "fluid.uploader.html5Strategy.remote", {
funcName: "fluid.uploader.html5Strategy.rawMIMESender"
});



/************************************
* HTML5 Strategy's Local Behaviour *
************************************/

fluid.uploader.html5Strategy.local = function (queue, legacyBrowserFileLimit, options) {
var that = fluid.initLittleComponent("fluid.uploader.html5Strategy.local", options);
that.queue = queue;
Expand Down
Expand Up @@ -487,18 +487,23 @@ https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
jqUnit.assertEquals("Sanity check: the queue should contain 6 files", 6, localUploader.queue.files.length);
});

html5UploaderTests.test("doFormDataUpload tests", function () {
html5UploaderTests.test("formDataSender tests", function () {
var queueSettings = {
uploadURL: "/home/Uploader",
postParams: {
name: "HTML5",
id: "8"
}
};
};

var xhr = fluid.tests.uploader.html5.mockXHR();
var formData = fluid.tests.uploader.mockFormData();
fluid.uploader.html5Strategy.doFormDataUpload(file1, queueSettings, xhr, formData);
var sender = fluid.uploader.html5Strategy.formDataSender({
invokers: {
createFormData: "fluid.tests.uploader.mockFormData"
}
});

var formData = sender.send(file1, queueSettings, xhr);
jqUnit.assertEquals("The correct file is appended", file1.id, formData.data.file.id);
jqUnit.assertEquals("postParam is correctly appended to FormData", "HTML5", formData.data.name);
jqUnit.assertEquals("postParam is correctly appended to FormData", 8, formData.data.id);
Expand All @@ -515,7 +520,8 @@ https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
};

var xhr = fluid.tests.uploader.html5.mockXHR();
fluid.uploader.html5Strategy.doManualMultipartUpload(file1, queueSettings, xhr);
var sender = fluid.uploader.html5Strategy.rawMIMESender();
sender.send(file1, queueSettings, xhr);
jqUnit.assertEquals("XHR receives the proper method", "POST", xhr.method);
jqUnit.assertEquals("XHR url is set", "/home/Uploader", xhr.url);
jqUnit.assertTrue("XHR to execute asynchronously", xhr.async);
Expand Down
4 changes: 2 additions & 2 deletions src/webapp/tests/component-tests/uploader/js/UploaderTests.js
Expand Up @@ -298,8 +298,8 @@ https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
for (var i = 0; i < xhrStatus.length; i++) {
addFiles(uploader);
var file = uploader.queue.getReadyFiles()[0];
var xhr = fluid.uploader.html5Strategy.monitorFileUploadXHR(
file, uploader.events, createXHR(xhrStatus[i]));
var xhr = createXHR(xhrStatus[i]);
fluid.uploader.html5Strategy.monitorFileUploadXHR(file, uploader.events, xhr);
xhr.onreadystatechange();
jqUnit.assertEquals("The file status is updated", fileStatus[i], file.filestatus);

Expand Down

0 comments on commit b62f829

Please sign in to comment.