Skip to content
This repository has been archived by the owner on Nov 20, 2018. It is now read-only.

Commit

Permalink
feat($session): #784 - ajax requester, session module, more options
Browse files Browse the repository at this point in the history
  • Loading branch information
Ray Nicholus committed Dec 19, 2013
1 parent 2fe4b4f commit 85585f3
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 8 deletions.
6 changes: 3 additions & 3 deletions client/js/ajax.requester.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ qq.AjaxRequester = function (o) {
allowXRequestedWithAndCacheControl: true,
successfulResponseCodes: {
"DELETE": [200, 202, 204],
"POST": [200, 204]
"POST": [200, 204],
"GET": [200]
},
cors: {
expected: false,
sendCredentials: false
},
log: function (str, level) {},
onSend: function (id) {},
onComplete: function (id, xhrOrXdr, isError) {},
onCancel: function (id) {}
onComplete: function (id, xhrOrXdr, isError) {}
};

qq.extend(options, o);
Expand Down
62 changes: 62 additions & 0 deletions client/js/session.ajax.requester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*globals qq, XMLHttpRequest*/
/**
* Thin module used to send GET requests to the server, expecting information about session
* data used to initialize an uploader instance.
*
* @param spec Various options used to influence the associated request.
* @constructor
*/
qq.SessionAjaxRequester = function(spec) {
"use strict";

var requester,
options = {
endpoint: null,
customHeaders: {},
params: {},
cors: {
expected: false,
sendCredentials: false
},
onComplete: function(response, success, xhrOrXdr) {},
log: function(str, level) {}
};

qq.extend(options, spec);

function onComplete(id, xhrOrXdr, isError) {
var response = null;

/* jshint eqnull:true */
if (xhrOrXdr.responseText != null) {
response = qq.parseJson(xhrOrXdr.responseText);
}

options.onComplete(response, !isError, xhrOrXdr);
}

requester = new qq.AjaxRequester({
validMethods: ["GET"],
method: "GET",
endpointStore: {
getEndpoint: function() {
return options.endpoint;
}
},
customHeaders: options.customHeaders,
log: options.log,
onComplete: onComplete,
cors: options.cors
});


qq.extend(this, {
queryServer: function() {
options.log("Session query request.");

requester.initTransport("sessionRefresh")
.withParams(options.params)
.send();
}
});
};
62 changes: 62 additions & 0 deletions client/js/session.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* globals qq */
/**
* Module used to control populating the initial list of files.
*
* @constructor
*/
qq.Session = function(spec) {
"use strict";

var options = {
endpoint: null,
params: {},
customHeaders: {},
cors: {},
log: function(message, level) {}
};

qq.extend(options, spec, true);


function isJsonResponseValid(response) {
if (qq.isArray(response)) {
return true;
}

options.log("Session response is not an array.", "error");
}

function handleFileItems(fileItems, success, xhrOrXdr, promise) {
success = isJsonResponseValid(fileItems);

if (success) {
qq.each(fileItems, function(idx, fileItem) {
// TODO Create ID for the file item (need to abstract this out of the handlers)
// TODO Need to delegate UUID, size, name retrieval out of handlers to uploadData module
// TODO Populate UUID, size, name, delete endpoint, thumbnail url, delete params
// TODO Add file item to uploadData module
// TODO Ensure file item is rendered in UI mode w/ size, name, delete button, success indicator, preview
});
}

promise[success ? "success" : "failure"](fileItems, xhrOrXdr);
}

// Initiate a call to the server that will be used to populate the initial file list.
// Returns a `qq.Promise`.
this.refresh = function() {
/*jshint indent:false */
var refreshEffort = new qq.Promise(),
refreshCompleteCallback = function(response, success, xhrOrXdr) {
handleFileItems(response, success, xhrOrXdr, refreshEffort);
},
requsterOptions = qq.extend({}, options),
requester = new qq.SessionAjaxRequester(
qq.extend(requsterOptions, {onComplete: refreshCompleteCallback})
);

requester.queryServer();

return refreshEffort;
};
};
32 changes: 29 additions & 3 deletions client/js/uploader.basic.api.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,8 @@
this._uploadData.reset();
this._buttonIdsForFileIds = [];

if (this._pasteHandler) {
this._pasteHandler.reset();
}
this._pasteHandler && this._pasteHandler.reset();
this._refreshSessionData();
},

addFiles: function(filesOrInputs, params, endpoint) {
Expand Down Expand Up @@ -335,6 +334,33 @@
* Defines the private (internal) API for FineUploaderBasic mode.
*/
qq.basePrivateApi = {
// Attempts to refresh session data only if the `qq.Session` module exists
// and a session endpoint has been specified. The `onSessionRequestComplete`
// callback will be invoked once the refresh is complete.
_refreshSessionData: function() {
var self = this,
options = this._options.session;

/* jshint eqnull:true */
if (qq.Session && this._options.session.endpoint != null) {
if (!this._session) {
qq.extend(options, this._options.cors);
options.log = this.log;

this._session = new qq.Session(options);
}

this._session.refresh().then(function(response, xhrOrXdr) {

self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr);

}, function(response, xhrOrXdr) {

self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr);
});
}
},

// Updates internal state when a new file has been received, and adds it along with its ID to a passed array.
_handleNewFile: function(file, newFileWrapperList) {
var id = this._handler.add(file);
Expand Down
6 changes: 5 additions & 1 deletion client/js/uploader.basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
onDelete: function(id){},
onDeleteComplete: function(id, xhrOrXdr, isError){},
onPasteReceived: function(blob) {},
onStatusChange: function(id, oldStatus, newStatus) {}
onStatusChange: function(id, oldStatus, newStatus) {},
onSessionRequestComplete: function(response, success, xhrOrXdr) {}
},

messages: {
Expand Down Expand Up @@ -163,6 +164,8 @@
// during initialization and optionally after a `reset`.
session: {
endpoint: null,
params: {},
customHeaders: {},
refreshOnReset: true
}
};
Expand Down Expand Up @@ -217,6 +220,7 @@
this._preventLeaveInProgress();

this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this));
this._refreshSessionData();
};

// Define the private & public API methods.
Expand Down
10 changes: 10 additions & 0 deletions docs/api/events.jmd
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ Called just before a file upload is resumed. See the `uploadChunk` event for mo

----

onSessionRequestComplete: function(response, success, xhrOrXdr) {}

#### sessionRequestComplete

**Parameters**: Object response, Boolean success, XMLHttpRequest || XDomainRequest xhrOrXdr

Invoked when a session request has completed.

----

#### statusChange

**Parameters**: Integer id, String oldStatus, String newStatus
Expand Down
2 changes: 2 additions & 0 deletions docs/api/options.jmd
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ See the [Initialize File List feature page](../features/session.html) for more d
{{ options_table(
(
("endpoint", "`String`", "`null`", "If non-null, Fine Uploader will send a GET request on startup to this endpoint, expecting a JSON response containing data about the initial file list to populate."),
("params", "`Object`", "`{}`", "Any parameters you would like passed with the associated GET request to your server."),
("customHeaders", "`Object`", "`{}`", "Any additional headers you would like included with the GET request sent to your server."),
("refreshOnReset", "`Boolean`", "`true`", "Set this to `false` if you do not want the file list to be retrieved from the server as part of a reset."),
)
) }}
Expand Down
7 changes: 6 additions & 1 deletion lib/modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ var fineUploaderModules = {
"@fuDndModule",
"@fuDeleteFileModule",
"@fuImagePreviewModule",
"@fuImageValidationModule"
"@fuImageValidationModule",
"@fuSessionModule"
],

"fuUiModules": [
Expand Down Expand Up @@ -133,6 +134,10 @@ var fineUploaderModules = {
"client/js/ui.handler.focus.filenameinput.js",
"client/js/ui.handler.edit.filename.js"
],
"fuSessionModule": [
"client/js/session.js",
"client/js/session.ajax.requester.js"
],
"fuIframeXssResponse": [
"client/js/iframe.xss.response.js"
],
Expand Down

0 comments on commit 85585f3

Please sign in to comment.