1
YUI.add('musicstore-status', function (Y, NAME) {
5
* DownloadStatus class constructor
7
* TODO Refactor: don't touch the DOM so much, store values in local object
9
* Class to monitor a list of downloads represented in rows of a table,
10
* state is stored as data attributes on those rows. Once all downloads have
11
* reached a 'completed state' polling stops but can be restarted at user
12
* request by clicking on a table row.
16
/* Any frequently used shortcuts, strings and constants */
17
var ONEERROR = "one:error";
20
function DownloadStatus() {
21
DownloadStatus.superclass.constructor.apply(this, arguments);
24
DownloadStatus.NAME = "downloadStatus";
26
DownloadStatus.ATTRS = {
27
dataNodes: { value: null },
30
value: 10000, // 10 seconds
31
validator: function(val) {
32
return Y.Lang.isNumber(val);
34
setter: function(val) {
35
this.pollingInterval = val;
41
// comepleted states used as a based for when to stop polling.
47
"downloaded-not-present"
51
// Get nodes within the srcNode.
52
DownloadStatus.HTML_PARSER = {
53
// DataNodes which will have the data attrs.
54
dataNodes: ['tbody tr']
57
Y.extend(DownloadStatus, Y.Widget, {
59
// set up instance specific state
60
initializer: function(config) {
61
if (config.statusCheckUrl && config.statusCheckUrl.length) {
62
this.statusCheckUrl = config.statusCheckUrl;
64
throw new Error("one-musicstore-status: need a status check url");
69
var bb = this.get("boundingBox");
70
this.pollNotification = bb.one(".notification");
71
this.pollNotification.one(".cta").on("click", function() {
72
this.checkStatus(false);
79
this.checkStatus(false);
82
destructor: function() {
83
clearInterval(this.interval);
87
* Enum for css class name values
92
// The data attribute for the dld key
93
dldIdAttrKey: "data-dld-id",
94
// The data attrubyte for the status.
95
dldStatusAttrKey: "data-dld-status",
96
// Description node selector
97
dldStatusDescSel: ".dld-status-desc",
98
// Where to find the class prefixed by classStatusPrefix
99
dldStatusClassSel: ".dld-status"
103
* DownloadStatus's common class prefix for statuses.
106
CLASS_STATUS_PREFIX: "status-",
115
* Poll count store for downloads
120
setPollTimer: function() {
121
this.interval = setInterval(Y.bind(this.checkStatus, this), this.pollingInterval);
125
* parse the nodes for status data
127
getStatusData: function() {
130
dldIdAttrKey = this.SELECTORS.dldIdAttrKey,
131
completedStates = Y.Array(this.get("completedStates"));
133
this.get("dataNodes").each(function(node) {
134
var key = node.getAttribute(dldIdAttrKey),
135
dldStatusAttrKey = this.SELECTORS.dldStatusAttrKey,
136
nodeStatus = node.getAttribute(dldStatusAttrKey);
138
// don't ask about stuff which is polled out or completed
139
if ( Y.Array.indexOf(completedStates, nodeStatus) === -1) {
141
dldData[key].status = this.parseNode(node);
148
parseNode: function(node) {
149
var dldStatusAttrKey = this.SELECTORS.dldStatusAttrKey;
150
return node.getAttribute(dldStatusAttrKey);
153
checkStatus: function(poll) {
154
// Get data for all the downloads
155
if (this.pollCount < this.POLL_MAX || poll === false) {
156
var data = this.getStatusData();
158
if (Y.Object.isEmpty(data)) {
163
this.postDownloadData(data);
167
this.pollNotification.addClass("show");
172
* postDownloadData. Send the download data...
174
* @param {Object} dldData all the data on the downloads
175
* @param {?Object} io Y.IO object
177
postDownloadData: function(dldData, io) {
178
io = io || new Y.IO();
181
data: {'song_list': Y.JSON.stringify(dldData),
182
'csrfmiddlewaretoken': YUI.Env.CSRF_TOKEN},
185
"success": this.onSuccess,
186
"failure": this.onFailure
190
request = io.send(this.statusCheckUrl, cfg);
196
* Take the response data from the statusCheck service and store the
197
* values in the attributes of the download elements, as well as
198
* setting relevant classes and content
201
onSuccess: function(tid, response) {
202
var respData = Y.JSON.parse(response.responseText),
203
srcNode = this.get("srcNode"),
204
dldIdAttrKey = this.SELECTORS.dldIdAttrKey,
205
dldStatusAttrKey = this.SELECTORS.dldStatusAttrKey,
206
continuePolling = false,
207
completedStates = Y.Array(this.get("completedStates")),
217
for (key in respData) {
218
selector = '['+ dldIdAttrKey + '="' + key + '"]';
219
dataNode = srcNode.one(selector),
220
oldStatus = dataNode.getAttribute(dldStatusAttrKey),
221
descStatusClassNode = dataNode.one(this.SELECTORS.dldStatusClassSel),
222
descNode = dataNode.one(this.SELECTORS.dldStatusDescSel),
223
nodeStatus = respData[key].status.toLowerCase(),
224
classStatusPrefix = this.CLASS_STATUS_PREFIX;
228
if (oldStatus !== nodeStatus) {
230
if (descStatusClassNode) {
231
// Remove current status
232
descStatusClassNode.removeClass(classStatusPrefix + oldStatus);
233
// Replace with new status
234
descStatusClassNode.addClass(classStatusPrefix + nodeStatus);
237
// Update description
239
descNode.set("text", respData[key].status_desc);
241
// Update status attr
242
dataNode.setAttribute(dldStatusAttrKey, nodeStatus);
247
if ( Y.Array.indexOf(completedStates, nodeStatus) === -1 ) {
248
continuePolling = true;
252
// if we're all complete, remove the poll timer
253
if (!continuePolling) {
257
if (!continuePolling && this.pollNotification && this.pollNotification.hasClass("show")) {
258
this.pollNotification.removeClass("show");
261
// Return continuePolling to add testing.
262
return continuePolling;
265
onFailure: function () {
266
Y.Global.fire(ONEERROR);
270
* remove the timer (stop polling) once we've reached POLL_MAX or
271
* all items are at a complete status
273
removeTimer: function() {
275
clearInterval(this.interval);
276
delete this.interval;
282
Y.namespace("U1MS").DownloadStatus = DownloadStatus;
285
}, '@VERSION@', {"requires": ["widget", "io", "json"]});