-
-
Save Asmod4n/28e5440fd47af471da9c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//= require external/crypto-js/build/rollups/sha512.js | |
//= require external/crypto-js/build/components/lib-typedarrays.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
messageHandler = (event) -> | |
if 'cmd' of event.data | |
switch event.data.cmd | |
when 'localStorage.push' | |
if storedFiles = localStorage.getItem(event.data.key) | |
storedFiles = JSON.parse(storedFiles) | |
storedFiles.push event.data.value | |
localStorage.setItem event.data.key, JSON.stringify(storedFiles) | |
else | |
localStorage.setItem event.data.key, JSON.stringify([event.data.value]) | |
when 'localStorage.del' then localStorage.removeItem event.data.key | |
when 'print' then console.log event.data.message | |
$('form').submit (event) -> | |
event.preventDefault() | |
worker = new Worker("<%= javascript_path('form_worker.js') %>") | |
worker.addEventListener 'message', messageHandler, false | |
form = new Array() | |
$(this).find('input, textarea, select').each (index, element) -> | |
if element.type is 'file' | |
form.push | |
name: element.name | |
type: element.type | |
data: element.files | |
else | |
form.push | |
name: element.name | |
type: element.type | |
data: $(this).val() | |
worker.postMessage | |
cmd: 'tryit' | |
form: form |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#= require internal/js/crypto.js | |
#= require internal/js/xhr2-FormData.js | |
chunkUpload = (file, length, sha512, formUUID, chunkCount, chunk) -> | |
formData = new FormData() | |
formData.append 'ffl.file', JSON.stringify( | |
name: file.name | |
size: file.size | |
type: file.type | |
length: length | |
sha512: sha512 | |
formUUID: formUUID | |
chunkNumber: chunkCount.currentNumber | |
numOfChunks: chunkCount.numOfChunks | |
) | |
formData.append 'ffl.chunk', chunk | |
xhr = new XMLHttpRequest() | |
xhr.open 'POST', '/application/', false | |
xhr.setRequestHeader 'Accept', 'application/json' | |
xhr.setRequestHeader 'X-Form-UUID', formUUID | |
xhr.send formData | |
postMessage | |
cmd: 'print' | |
message: JSON.stringify(xhr.response) | |
if xhr.status < 400 | |
response = JSON.parse(xhr.response) | |
if response.success is true | |
postMessage | |
cmd: 'localStorage.push' | |
key: sha512 | |
value: chunkCount.currentNumber | |
chunkCount.numOfUploadedChunks++ | |
if chunkCount.numOfUploadedChunks is chunkCount.numOfChunks | |
postMessage | |
cmd: 'localStorage.del' | |
key: sha512 | |
upload = (file, length, sha512, formUUID) -> | |
chunkSize = 1024 * 512 | |
chunkCount = | |
currentNumber: 1 | |
numOfChunks: Math.ceil(file.size / chunkSize) | |
numOfUploadedChunks: 0 | |
chunkStart = 0 | |
chunkEnd = chunkSize | |
while chunkStart < file.size | |
if file.slice | |
currentChunk = file.slice(chunkStart, chunkEnd) | |
else if file.mozSlice | |
currentChunk = file.mozSlice(chunkStart, chunkEnd) | |
else currentChunk = file.webkitSlice(chunkStart, chunkEnd) if file.webkitSlice | |
chunkUpload file, length, sha512, formUUID, chunkCount, currentChunk | |
chunkCount.currentNumber++ | |
chunkStart = chunkEnd | |
chunkEnd = chunkEnd + chunkSize | |
UUID = -> | |
uuid = '' | |
i = 0 | |
while i < 32 | |
random = Math.random() * 16 | 0 | |
uuid += '-' if i is 8 or i is 12 or i is 16 or i is 20 | |
uuid += ((if i is 12 then 4 else ((if i is 16 then (random & 3 | 8) else random)))).toString(16) | |
i++ | |
uuid | |
uploadFiles = (files, formUUID) -> | |
reader = new FileReaderSync() | |
i = 0 | |
while i < files.length | |
upload files[i], files.length, CryptoJS.SHA512(CryptoJS.lib.WordArray.create(reader.readAsArrayBuffer(files[i]))).toString(CryptoJS.enc.Hex), formUUID | |
i++ | |
uploadForm = (form) -> | |
formUUID = UUID() | |
postMessage | |
cmd: 'print' | |
message: formUUID | |
formData = new FormData() | |
form.forEach (element, index, array) -> | |
if element.type is 'file' | |
array.splice index, 1 | |
uploadFiles element.data, formUUID | |
else | |
formData.append element.name, element.data | |
xhr = new XMLHttpRequest() | |
xhr.open 'POST', '/application/', false | |
xhr.setRequestHeader 'Accept', 'application/json' | |
xhr.setRequestHeader 'X-Form-UUID', formUUID | |
xhr.send formData | |
postMessage | |
cmd: 'print' | |
message: JSON.stringify(xhr.response) | |
self.close() | |
self.addEventListener 'message', ((event) -> | |
if 'cmd' of event.data | |
switch event.data.cmd | |
when 'tryit' | |
uploadForm event.data.form | |
), false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* FormData for XMLHttpRequest 2 - Polyfill for Web Worker (c) 2012 Rob W | |
* License: Creative Commons BY - http://creativecommons.org/licenses/by/3.0/ | |
* - append(name, value[, filename]) | |
* - toString: Returns an ArrayBuffer object | |
* | |
* Specification: http://www.w3.org/TR/XMLHttpRequest/#formdata | |
* http://www.w3.org/TR/XMLHttpRequest/#the-send-method | |
* The .append() implementation also accepts Uint8Array and ArrayBuffer objects | |
* Web Workers do not natively support FormData: | |
* http://dev.w3.org/html5/workers/#apis-available-to-workers | |
**/ | |
(function() { | |
// Export variable to the global scope | |
(this == undefined ? self : this)['FormData'] = FormData; | |
var ___send$rw = XMLHttpRequest.prototype.send; | |
XMLHttpRequest.prototype['send'] = function(data) { | |
if (data instanceof FormData) { | |
if (!data.__endedMultipart) data.__append('--' + data.boundary + '--\r\n'); | |
data.__endedMultipart = true; | |
this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + data.boundary); | |
data = new Uint8Array(data.data).buffer; | |
} | |
// Invoke original XHR.send | |
return ___send$rw.call(this, data); | |
}; | |
function FormData() { | |
// Force a Constructor | |
if (!(this instanceof FormData)) return new FormData(); | |
// Generate a random boundary - This must be unique with respect to the form's contents. | |
this.boundary = '------RWWorkerFormDataBoundary' + Math.random().toString(36); | |
var internal_data = this.data = []; | |
/** | |
* Internal method. | |
* @param inp String | ArrayBuffer | Uint8Array Input | |
*/ | |
this.__append = function(inp) { | |
var i=0, len; | |
if (typeof inp === 'string') { | |
for (len=inp.length; i<len; i++) | |
internal_data.push(inp.charCodeAt(i) & 0xff); | |
} else if (inp && inp.byteLength) {/*If ArrayBuffer or typed array */ | |
if (!('byteOffset' in inp)) /* If ArrayBuffer, wrap in view */ | |
inp = new Uint8Array(inp); | |
for (len=inp.byteLength; i<len; i++) | |
internal_data.push(inp[i] & 0xff); | |
} | |
}; | |
} | |
/** | |
* @param name String Key name | |
* @param value String|Blob|File|Uint8Array|ArrayBuffer Value | |
* @param filename String Optional File name (when value is not a string). | |
**/ | |
FormData.prototype['append'] = function(name, value, filename) { | |
if (this.__endedMultipart) { | |
// Truncate the closing boundary | |
this.data.length -= this.boundary.length + 6; | |
this.__endedMultipart = false; | |
} | |
var valueType = Object.prototype.toString.call(value), | |
part = '--' + this.boundary + '\r\n' + | |
'Content-Disposition: form-data; name="' + name + '"'; | |
if (/^\[object (?:Blob|File)(?:Constructor)?\]$/.test(valueType)) { | |
return this.append(name, | |
new Uint8Array(new FileReaderSync().readAsArrayBuffer(value)), | |
filename || value.name); | |
} else if (/^\[object (?:Uint8Array|ArrayBuffer)(?:Constructor)?\]$/.test(valueType)) { | |
part += '; filename="'+ (filename || 'blob').replace(/"/g,'%22') +'"\r\n'; | |
part += 'Content-Type: application/octet-stream\r\n\r\n'; | |
this.__append(part); | |
this.__append(value); | |
part = '\r\n'; | |
} else { | |
part += '\r\n\r\n' + value + '\r\n'; | |
} | |
this.__append(part); | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment