public
Description: Upload progress bar working with apache, nginx and lighttpd upload progress modules
Homepage:
Clone URL: git://github.com/drogus/prototype-upload-progress.git
sAlexander (author)
Thu Sep 25 19:40:12 -0700 2008
drogus (committer)
Sat Dec 20 11:25:15 -0800 2008
prototype-upload-progress / prototype.uploadProgress.js
100644 134 lines (120 sloc) 4.863 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* prototype.uploadProgress
*
* Copyright (c) 2008 Peter Sarnacki (drogomir.com)
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
*/
var UploadProgressMethods = {
uploadProgress: function(element, options) {
options == options || {};
options = Object.extend({
client_interval: 500,
      interval:10000,
progressBar: "progressbar",
progressUrl: "/progress",
      previous_percent: 0,
      previous_time: 0,
      current_percent: 0,
      rate: 0,
start: function() {},
uploading: function() {},
complete: function() {},
success: function() {},
error: function() {},
uploadProgressPath: '/javascripts/prototype.js',
prototypePath: '/javascripts/prototype.uploadProgress.js',
      server_timer: "",
      client_timer: ""
}, options);
 
/* tried to add iframe after submit (to not always load it) but it won't work.
safari can't get scripts properly while submitting files */
if(Prototype.Browser.WebKit && top.document == document) {
 
/* iframe to send ajax requests in safari
thanks to Michele Finotto for idea */
iframe = document.createElement('iframe');
iframe.name = "progressFrame";
$(iframe).setStyle({width: '0', height: '0', position: 'absolute', top: '-3000px'});
document.body.appendChild(iframe);
 
var d = iframe.contentWindow.document;
d.open();
/* weird - safari won't load scripts without this lines... */
d.write('<html><head></head><body></body></html>');
d.close();
 
var b = d.body;
var s = d.createElement('script');
s.src = options.prototypePath;
/* must be sure that jquery is loaded */
s.onload = function() {
var s1 = d.createElement('script');
s1.src = options.uploadProgressPath;
b.appendChild(s1);
}
b.appendChild(s);
}
 
Event.observe(element, 'submit', function() {
var uuid = "";
for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); }
 
options.uuid = uuid;
/* start callback */
options.start();
 
/* patch the form-action tag to include the progress-id
if X-Progress-ID has been already added just replace it */
                        if(old_id = /X-Progress-ID=([^&]+)/.exec($(this).readAttribute("action"))) {
                          var action = $(this).readAttribute("action").replace(old_id[1], uuid);
                          $(this).writeAttribute("action", action);
                        } else {
$(this).writeAttribute("action", $(this).readAttribute("action") + "?X-Progress-ID=" + uuid);
}
var uploadProgress = Prototype.Browser.WebKit ? progressFrame.Prototype.uploadProgress : Prototype.uploadProgress;
      var uploadMovement = Prototype.Browser.WebKit ? progressFrame.Prototype.uploadMovement : Prototype.uploadMovement;
options.server_timer = window.setInterval(function() { uploadProgress(this, options) }, options.interval);
      options.client_timer = window.setInterval(function() { uploadMovement(this, options) {, options.client_interval);
});
}
};
 
Element.addMethods(UploadProgressMethods);
 
PrototypeUploadProgressMethods = {
  uploadMovement: function(element, options) {
    if (upload_state == 'done' || options.current_percent > 100) {
      window.clearTimeout(options.client_timer);
    } else {
      options.current_percent = options.current_percent + options.rate
      var bar = Prototype.Browser.WebKit ? parent.document.getElementById(options.progressBar) : $(options.progressBar);
      bar.setStyle({width: Math.floor(options.current_percent) + '%'});
    }
  }
      
uploadProgress: function(element, options) {
new Ajax.Request(options.progressUrl, {
method: 'get',
parameters: 'X-Progress-ID='+ options.uuid,
onSuccess: function(xhr){
var upload = xhr.responseText.evalJSON();
        var current_time = new Date();
        var miliseconds = current_time.getTime();
upload.percents = Math.floor((upload.received / upload.size)*100);
if (upload.state == 'uploading') {
          if (miliseconds - previous_time !=0 && (100 - upload.percents) !=0) {
            options.rate = (upload.percents - options.previous_percent) * options.client_interval / (miliseconds - options.previous_time) * ( (100-options.current_percent) / (100 - upload.percents) )
            options.previous_time = miliseconds;
            options.previous_percent = upload.percents;
          }
}
/* we are done, stop the interval */
if (upload.state == 'done' || upload.state == 'error') {
window.clearTimeout(options.server_timer);
options.complete(upload);
}
 
if (upload.state == 'done') {
options.success(upload);
}
 
if (upload.state == 'error') {
options.error(upload);
}
}
});
}
};
 
Object.extend(Prototype, PrototypeUploadProgressMethods);