o: ActiveSupport::Cache::Entry :@compressedF:@created_atf1359319053.437553:@expires_in0: @value"¹H{I" class:EFI"ProcessedAsset;FI"logical_path;FI""anjlab/uploads/handler.xhr.js;TI" pathname;FI"Y/Users/yury/Work/uploads/app/assets/javascripts/anjlab/uploads/handler.xhr.js.coffee;TI"content_type;FI"application/javascript;FI" mtime;FI"2013-01-28T00:35:39+04:00;FI" length;Fi‡EI" digest;F"%52d1403963a65847731678d873e6ffc5I" source;FI"‡E(function() { var utils, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; utils = this.AnjLab.Uploads.Utils; this.AnjLab.Uploads.UploadHandlerXhr = (function(_super) { __extends(UploadHandlerXhr, _super); function UploadHandlerXhr(options) { this.reset = __bind(this.reset, this); UploadHandlerXhr.__super__.constructor.call(this, options); this.fileState = []; this.cookieItemDelimiter = "|"; this.chunkFiles = this.options.chunking.enabled && utils.isFileChunkingSupported(); this.resumeEnabled = this.options.resume.enabled && this.chunkFiles && utils.areCookiesEnabled(); this.resumeId = this.getResumeId(); this.multipart = this.options.forceMultipart; } UploadHandlerXhr.prototype.addChunkingSpecificParams = function(id, params, chunkData) { var name, size; size = this.getSize(id); name = this.getName(id); params[this.options.chunking.paramNames.partIndex] = chunkData.part; params[this.options.chunking.paramNames.partByteOffset] = chunkData.start; params[this.options.chunking.paramNames.chunkSize] = chunkData.end - chunkData.start; params[this.options.chunking.paramNames.totalParts] = chunkData.count; params[this.options.totalFileSizeParamName] = size; if (this.multipart) { return params[this.options.chunking.paramNames.filename] = name; } }; UploadHandlerXhr.prototype.addResumeSpecificParams = function(params) { return params[this.options.resume.paramNames.resuming] = true; }; UploadHandlerXhr.prototype.getChunk = function(file, startByte, endByte) { if (file.slice) { return file.slice(startByte, endByte); } else if (file.mozSlice) { return file.mozSlice(startByte, endByte); } else if (file.webkitSlice) { return file.webkitSlice(startByte, endByte); } }; UploadHandlerXhr.prototype.getChunkData = function(id, chunkIndex) { var chunkSize, endBytes, file, fileSize, startBytes, totalChunks; chunkSize = this.options.chunking.partSize; fileSize = this.getSize(id); file = this.fileState[id].file; startBytes = chunkSize * chunkIndex; endBytes = startBytes + chunkSize >= (fileSize ? fileSize : startBytes + chunkSize); totalChunks = this.getTotalChunks(id); return { part: chunkIndex, start: startBytes, end: endBytes, count: totalChunks, blob: this.getChunk(file, startBytes, endBytes) }; }; UploadHandlerXhr.prototype.getTotalChunks = function(id) { return Math.ceil(this.getSize(id) / this.options.chunking.partSize); }; UploadHandlerXhr.prototype.createXhr = function(id) { return this.fileState[id].xhr = new XMLHttpRequest(); }; UploadHandlerXhr.prototype.setParamsAndGetEntityToSend = function(params, xhr, fileOrBlob, id) { var csrf_param, csrf_token, endpoint, formData, name, protocol, size, url; formData = new FormData(); protocol = this.options.demoMode ? "GET" : "POST"; endpoint = this.options.endpointStore.getEndpoint(id); url = endpoint; name = this.getName(id); size = this.getSize(id); params[this.options.uuidParamName] = this.fileState[id].uuid; if (this.multipart) { params[this.options.totalFileSizeParamName] = size; } params[this.options.inputName] = name; params['_' + this.options.inputName] = name; params['utf8'] = '✓'; csrf_param = $("meta[name=csrf-param]").attr("content"); csrf_token = $("meta[name=csrf-token]").attr("content"); params[csrf_param] = csrf_token; url = endpoint + (/\?/.test(url) ? '&' : '?') + $.param(params); xhr.open(protocol, url, true); return fileOrBlob; }; UploadHandlerXhr.prototype.setHeaders = function(id, xhr) { var extraHeaders, file, name, val, _results; extraHeaders = this.options.customHeaders; name = this.getName(id); file = this.fileState[id].file; xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); xhr.setRequestHeader("Cache-Control", "no-cache"); xhr.setRequestHeader("Content-Type", "application/octet-stream"); xhr.setRequestHeader("X-Mime-Type", file.type); _results = []; for (name in extraHeaders) { if (!__hasProp.call(extraHeaders, name)) continue; val = extraHeaders[name]; _results.push(xhr.setRequestHeader(name, val)); } return _results; }; UploadHandlerXhr.prototype.handleCompletedFile = function(id, response, xhr) { var name, size; name = this.getName(id); size = this.getSize(id); this.fileState[id].attemptingResume = false; this.options.onProgress(id, name, size, size); this.options.onComplete(id, name, response, xhr); delete this.fileState[id].xhr; return this.uploadComplete(id); }; UploadHandlerXhr.prototype.handleSuccessfullyCompletedChunk = function(id, response, xhr) { var chunkData, chunkIdx; chunkIdx = this.fileState[id].remainingChunkIdxs.shift(); chunkData = this.getChunkData(id, chunkIdx); this.fileState[id].attemptingResume = false; this.fileState[id].loaded += chunkData.end - chunkData.start; if (this.fileState[id].remainingChunkIdxs.length > 0) { return this.uploadNextChunk(id); } else { this.deletePersistedChunkData(id); return this.handleCompletedFile(id, response, xhr); } }; UploadHandlerXhr.prototype.isErrorResponse = function(xhr, response) { return xhr.status !== 200 || !response.success || response.reset; }; UploadHandlerXhr.prototype.parseResponse = function(xhr) { try { return utils.parseJson(xhr.responseText); } catch (error) { this.log("Error when attempting to parse xhr response text (" + error + ")", 'error'); return {}; } }; UploadHandlerXhr.prototype.handleResetResponse = function(id) { this.log('Server has ordered chunking effort to be restarted on next attempt for file ID ' + id, 'error'); if (this.resumeEnabled) { this.deletePersistedChunkData(id); } this.fileState[id].remainingChunkIdxs = []; return delete this.fileState[id].loaded; }; UploadHandlerXhr.prototype.handleResetResponseOnResumeAttempt = function(id) { this.fileState[id].attemptingResume = false; this.log("Server has declared that it cannot handle resume for file ID " + id + " - starting from the first chunk", 'error'); return this.uploadFile(id, true); }; UploadHandlerXhr.prototype.getChunkDataForCallback = function(chunkData) { return { partIndex: chunkData.part, startByte: chunkData.start + 1, endByte: chunkData.end, totalParts: chunkData.count }; }; UploadHandlerXhr.prototype.getReadyStateChangeHandler = function(id, xhr) { var _this = this; return function() { if (xhr.readyState === 4) { return _this.onComplete(id, xhr); } }; }; UploadHandlerXhr.prototype.persistChunkData = function(id, chunkData) { var cookieExpDays, cookieName, cookieValue, fileUuid; fileUuid = this.getUuid(id); cookieName = this.getChunkDataCookieName(id); cookieValue = fileUuid + this.cookieItemDelimiter + chunkData.part; cookieExpDays = this.options.resume.cookiesExpireIn; return utils.setCookie(cookieName, cookieValue, cookieExpDays); }; UploadHandlerXhr.prototype.deletePersistedChunkData = function(id) { var cookieName; cookieName = this.getChunkDataCookieName(id); return utils.deleteCookie(cookieName); }; UploadHandlerXhr.prototype.getPersistedChunkData = function(id) { var chunkCookieValue, delimiterIndex, partIndex, uuid; chunkCookieValue = utils.getCookie(this.getChunkDataCookieName(id)); if (!chunkCookieValue) { return; } delimiterIndex = chunkCookieValue.indexOf(this.cookieItemDelimiter); uuid = chunkCookieValue.substr(0, delimiterIndex); partIndex = parseInt(chunkCookieValue.substr(delimiterIndex + 1, chunkCookieValue.length - delimiterIndex), 10); return { uuid: uuid, part: partIndex }; }; UploadHandlerXhr.prototype.handleNonResetErrorResponse = function(id, response, xhr) { if (this.options.onAutoRetry(id, this.getName(id), response, xhr)) { return; } return this.handleCompletedFile(id, response, xhr); }; UploadHandlerXhr.prototype.getChunkDataCookieName = function(id) { var fileSize, filename, maxChunkSize, parts; filename = this.getName(id); fileSize = this.getSize(id); maxChunkSize = this.options.chunking.partSize; parts = ['qqfilechunk', encodeURIComponent(filename), fileSize, maxChunkSize]; if (this.resumeId != null) { parts << this.resumeId; } return parts.join(this.cookieItemDelimiter); }; UploadHandlerXhr.prototype.getResumeId = function() { if ((this.options.resume.id != null) && !$.isFunction(this.options.resume.id) && !$.isObject(this.options.resume.id)) { return this.options.resume.id; } }; UploadHandlerXhr.prototype.uploadNextChunk = function(id) { var chunkData, name, params, size, toSend, xhr, _this = this; chunkData = this.getChunkData(id, this.fileState[id].remainingChunkIdxs[0]); xhr = this.createXhr(id); size = this.getSize(id); name = this.getName(id); if (this.fileState[id].loaded != null) { this.fileState[id].loaded = 0; } this.persistChunkData(id, chunkData); xhr.onreadystatechange = this.getReadyStateChangeHandler(id, xhr); xhr.upload.onprogress = function(e) { var totalLoaded; if (e.lengthComputable) { if (_this.fileState[id].loaded < size) { totalLoaded = e.loaded + _this.fileState[id].loaded; return _this.options.onProgress(id, name, totalLoaded, size); } } }; this.options.onUploadChunk(id, name, this.getChunkDataForCallback(chunkData)); params = this.options.paramsStore.getParams(id); this.addChunkingSpecificParams(id, params, chunkData); if (this.fileState[id].attemptingResume) { this.addResumeSpecificParams(params); } toSend = this.setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); this.setHeaders(id, xhr); this.log('Sending chunked upload request for ' + id + ": bytes " + (chunkData.start + 1) + "-" + chunkData.end + " of " + size); return xhr.send(toSend); }; UploadHandlerXhr.prototype.onComplete = function(id, xhr) { var response; if (!this.fileState[id]) { return; } this.log("xhr - server response received for " + id); this.log("responseText = " + xhr.responseText); response = this.parseResponse(xhr); if (this.isErrorResponse(xhr, response)) { if (response.reset) { this.handleResetResponse(id); } if (this.fileState[id].attemptingResume && response.reset) { return this.handleResetResponseOnResumeAttempt(id); } else { return this.handleNonResetErrorResponse(id, response, xhr); } } else if (this.chunkFiles) { return this.handleSuccessfullyCompletedChunk(id, response, xhr); } else { return this.handleCompletedFile(id, response, xhr); } }; UploadHandlerXhr.prototype.handleFileChunkingUpload = function(id, retry) { var currentChunkIndex, firstChunkDataForResume, firstChunkIndex, name, persistedChunkInfoForResume; name = this.getName(id); firstChunkIndex = 0; if (!this.fileState[id].remainingChunkIdxs || this.fileState[id].remainingChunkIdxs.length === 0) { this.fileState[id].remainingChunkIdxs = []; if (this.resumeEnabled && !retry) { persistedChunkInfoForResume = this.getPersistedChunkData(id); if (persistedChunkInfoForResume) { firstChunkDataForResume = this.getChunkData(id, persistedChunkInfoForResume.part); if (this.options.onResume(id, name, this.getChunkDataForCallback(firstChunkDataForResume)) !== false) { firstChunkIndex = persistedChunkInfoForResume.part; this.fileState[id].uuid = persistedChunkInfoForResume.uuid; this.fileState[id].loaded = firstChunkDataForResume.start; this.fileState[id].attemptingResume = true; this.log('Resuming ' + name + " at partition index " + firstChunkIndex); } } } currentChunkIndex = this.getTotalChunks(id) - 1; while (currentChunkIndex >= firstChunkIndex) { this.fileState[id].remainingChunkIdxs.unshift(currentChunkIndex); currentChunkIndex -= 1; } } return this.uploadNextChunk(id); }; UploadHandlerXhr.prototype.handleStandardFileUpload = function(id) { var file, name, params, toSend, xhr, _this = this; file = this.fileState[id].file; name = this.getName(id); this.fileState[id].loaded = 0; xhr = this.createXhr(id); xhr.upload.onprogress = function(e) { if (e.lengthComputable) { _this.fileState[id].loaded = e.loaded; return _this.options.onProgress(id, name, e.loaded, e.total); } }; xhr.onreadystatechange = this.getReadyStateChangeHandler(id, xhr); params = this.options.paramsStore.getParams(id); toSend = this.setParamsAndGetEntityToSend(params, xhr, file, id); this.setHeaders(id, xhr); this.log('Sending upload request for ' + id); return xhr.send(toSend); }; UploadHandlerXhr.prototype.add = function(file) { var id; if (!(file instanceof File)) { throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)'); } id = this.fileState.push({ file: file }) - 1; this.fileState[id].uuid = utils.getUniqueId(); return id; }; UploadHandlerXhr.prototype.getName = function(id) { var file, _ref; file = this.fileState[id].file; return (_ref = file.fileName) != null ? _ref : file.name; }; UploadHandlerXhr.prototype.getSize = function(id) { var file, _ref; file = this.fileState[id].file; return (_ref = file.fileSize) != null ? _ref : file.size; }; UploadHandlerXhr.prototype.getFile = function(id) { if (this.fileState[id]) { return this.fileState[id].file; } }; UploadHandlerXhr.prototype.getLoaded = function(id) { return this.fileState[id].loaded || 0; }; UploadHandlerXhr.prototype.isValid = function(id) { return this.fileState[id] != null; }; UploadHandlerXhr.prototype.reset = function() { UploadHandlerXhr.__super__.reset.call(this); return this.fileState = []; }; UploadHandlerXhr.prototype.getUuid = function(id) { return this.fileState[id].uuid; }; UploadHandlerXhr.prototype.uploadFile = function(id, retry) { var name; name = this.getName(id); this.options.onUpload(id, name); if (this.chunkFiles) { return this.handleFileChunkingUpload(id, retry); } else { return this.handleStandardFileUpload(id); } }; UploadHandlerXhr.prototype.cancelFile = function(id) { this.options.onCancel(id, this.getName(id)); if (this.fileState[id].xhr) { this.fileState[id].xhr.abort(); } if (this.resumeEnabled) { this.deletePersistedChunkData(id); } return delete this.fileState[id]; }; UploadHandlerXhr.prototype.getResumableFilesData = function() { var cookieName, cookieValueParts, cookiesNameParts, matchingCookieNames, resumableFilesData, _i, _len; matchingCookieNames = []; resumableFilesData = []; if (this.chunkFiles && this.resumeEnabled) { if (!(this.resumeId != null)) { matchingCookieNames = utils.getCookieNames(new RegExp("^qqfilechunk\\" + this.cookieItemDelimiter + ".+\\" + this.cookieItemDelimiter + "\\d+\\" + this.cookieItemDelimiter + this.options.chunking.partSize + "=")); } else { matchingCookieNames = utils.getCookieNames(new RegExp("^qqfilechunk\\" + this.cookieItemDelimiter + ".+\\" + this.cookieItemDelimiter + "\\d+\\" + this.cookieItemDelimiter + this.options.chunking.partSize + "\\" + this.cookieItemDelimiter + this.resumeId + "=")); } for (_i = 0, _len = matchingCookieNames.length; _i < _len; _i++) { cookieName = matchingCookieNames[_i]; cookiesNameParts = cookieName.split(this.cookieItemDelimiter); cookieValueParts = utils.getCookie(cookieName).split(this.cookieItemDelimiter); resumableFilesData.push({ name: decodeURIComponent(cookiesNameParts[1]), size: cookiesNameParts[2], uuid: cookieValueParts[0], partIdx: cookieValueParts[1] }); } return resumableFilesData; } else { return []; } }; return UploadHandlerXhr; })(this.AnjLab.Uploads.UploadHandler); }).call(this); ;TI"dependency_digest;F"%64b1859973f4f8cc90db2ce7bba4e423I"required_paths;F[I"Y/Users/yury/Work/uploads/app/assets/javascripts/anjlab/uploads/handler.xhr.js.coffee;TI"dependency_paths;F[{I" path;FI"Y/Users/yury/Work/uploads/app/assets/javascripts/anjlab/uploads/handler.xhr.js.coffee;TI" mtime;FI"2013-01-28T00:35:39+04:00;FI" digest;F"%934db535400757a19150d02881ae6965I" _version;F"%6776f581a4329e299531e1d52aa59832