(function(){

    var progressBar = function(el, data) {
        if(data.lengthComputable === false || el === null) return

        var pcnt = Math.round(data.loaded * 100 / data.total),
            bar  = el.querySelector('.bar')

        bar.style.width = pcnt + '%'
    }

    var request = function(method, url, data, progressEl, cb) {
        var req = new XMLHttpRequest()

        req.open(method, url, true)

        req.onload = function() {
            cb(req.status, req.responseText)
        }

        req.onerror = function() {
            alert('Network error.')
        }

        req.onprogress = function(data) {
            progressBar(progressEl, data)
        }

        req.send(data)
    }

    var parseURL = function(text) {
        var xml = new DOMParser().parseFromString(text, 'text/xml'),
            tag = xml.getElementsByTagName('Location')[0],
            url = unescape(tag.childNodes[0].nodeValue)

        return url
    }

    var update = function(el, status, xml) {
        var link = el.querySelector('.file-link'),
            url  = el.querySelector('.file-url')

        url.value = parseURL(xml)
        link.setAttribute('href', url.value)
        link.innerHTML = url.value.split('/').pop()

        el.className = 's3direct link-active'
        el.querySelector('.bar').style.width = '0%'
    }

    var disableSubmit = function(status) {
        var submitRow = document.querySelector('.submit-row'),
            buttons   = submitRow.querySelectorAll('input[type=submit]')

        ;[].forEach.call(buttons, function(el){
            el.disabled = status
        })
    }

    var upload = function(file, json, el) {
        var data = JSON.parse(json),
            form = new FormData(),
            url  = data['form_action']

        disableSubmit(true)
        el.className = 's3direct progress-active'
        delete data['form_action']

        Object.keys(data).forEach(function(key){
            form.append(key, data[key])
        })
        form.append('file', file)

        request('POST', url, form, el, function(status, xml){
            disableSubmit(false)
            if(status !== 201) return alert('Sorry, failed to upload to S3.')
            update(el, status, xml)
        })
    }

    var getUploadURL = function(e) {
        var el   = e.target.parentElement,
            file = el.querySelector('.file-input').files[0],
            url  = el.getAttribute('data-policy-url'),
            form = new FormData()

        form.append('type', file.type)
        form.append('name', file.name)

        request('POST', url, form, null, function(status, json){
            if(status !== 200) return alert('Sorry, could not get upload URL.')
            upload(file, json, el)
        })
    }

    var removeUpload = function(e) {
        e.preventDefault()

        var el = e.target.parentElement
        el.querySelector('.file-url').value = ''
        el.className = 's3direct form-active'
    }

    var addHandlers = function(el) {
        var url    = el.querySelector('.file-url'),
            input  = el.querySelector('.file-input'),
            remove = el.querySelector('.file-remove'),
            status = (url.value === '') ? 'form' : 'link'

        el.classList.add(status + '-active')

        remove.addEventListener('click', removeUpload, false)
        input.addEventListener('change', getUploadURL, false)
    }

    document.addEventListener('DOMContentLoaded', function(e) {
        ;[].forEach.call(document.querySelectorAll('.s3direct'), addHandlers)
    })

})()
@@ -42,24 +42,38 @@
 ion(el, data
+, showProgress
 ) %7B%0A        
@@ -114,19 +114,30 @@
  %7C%7C 
-el === null
+showProgress === false
 ) re
@@ -340,26 +340,32 @@
 , data, 
-p
+el, showP
 rogress
-El
 , cb) %7B%0A
@@ -683,24 +683,30 @@
 Bar(
-progressEl, data
+el, data, showProgress
 )%0A  
@@ -2096,16 +2096,22 @@
 orm, el,
+ true,
  functio
@@ -2345,16 +2345,20 @@
 ar el   
+    
 = e.targ
@@ -2392,16 +2392,20 @@
    file 
+    
 = el.que
@@ -2449,26 +2449,96 @@
            u
-rl
+ploadTo = el.querySelector('.file-upload-to').value,%0A            url    
   = el.getAt
@@ -2574,32 +2574,36 @@
            form 
+    
 = new FormData()
@@ -2681,16 +2681,59 @@
 le.name)
+%0A        form.append('upload_to', uploadTo)
 %0A%0A      
@@ -2765,12 +2765,17 @@
 rm, 
-null
+el, false
 , fu

Break out progress param.