uploader 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/app/controllers/uploader/uploads_controller.rb +74 -62
- data/app/helpers/uploader_helper.rb +1 -0
- data/app/views/uploads/_swf_javascript.html.erb +2 -2
- data/lib/active_record/acts/uploader_upload.rb +20 -1
- data/public/images/cancelbutton.gif +0 -0
- data/public/javascripts/swfupload/swfupload.js +102 -67
- data/public/javascripts/swfupload/swfupload.queue.js +79 -58
- data/public/javascripts/swfupload/swfupload.speed.js +342 -0
- data/public/javascripts/swfupload/swfupload.swfobject.js +4 -3
- data/public/stylesheets/swfupload.css +1 -1
- data/public/swf/swfupload.swf +0 -0
- data/rails/init.rb +3 -3
- data/test/rails_root/app/controllers/uploads_controller.rb +4 -0
- data/test/rails_root/config/environment.rb +3 -3
- data/test/rails_root/db/test.sqlite3 +0 -0
- data/test/rails_root/public/stylesheets/swfupload.css +1 -1
- data/test/rails_root/test/functional/uploads_controller_test.rb +53 -1
- data/test/rails_root/test/test.doc +0 -0
- data/test/rails_root/test/test.pdf +0 -0
- data/test/rails_root/test/test.xls +0 -0
- data/test/rails_root/test/test_helper.rb +5 -1
- data/uploader.gemspec +7 -2
- metadata +7 -2
data/README.rdoc
CHANGED
@@ -28,7 +28,7 @@ Another option is to use jRails
|
|
28
28
|
http://ennerchi.com/projects/jrails
|
29
29
|
|
30
30
|
=== Create a model for uploads.
|
31
|
-
|
31
|
+
Creat an 'Upload' model in upload.rb. acts_as_uploader accepts all valid options for paperclip via :has_attached_file => {}
|
32
32
|
|
33
33
|
class Upload < ActiveRecord::Base
|
34
34
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.5
|
@@ -7,7 +7,8 @@ class Uploader::UploadsController < ApplicationController
|
|
7
7
|
|
8
8
|
def create
|
9
9
|
# Standard, one-at-a-time, upload action
|
10
|
-
@upload =
|
10
|
+
@upload = Upload.new(params[:upload])
|
11
|
+
@upload.uploadable = @parent
|
11
12
|
@upload.creator = get_creator
|
12
13
|
@upload.save!
|
13
14
|
message = t('uploader.successful_upload')
|
@@ -34,12 +35,12 @@ class Uploader::UploadsController < ApplicationController
|
|
34
35
|
end
|
35
36
|
|
36
37
|
def swfupload
|
37
|
-
@upload =
|
38
|
+
@upload = Upload.new
|
38
39
|
@upload.is_public = true if params[:is_public] == true
|
39
40
|
@upload.creator = get_creator
|
41
|
+
@upload.uploadable = @parent
|
40
42
|
@upload.swfupload_local = params[:Filedata]
|
41
43
|
@upload.save!
|
42
|
-
@parent.uploads << @upload
|
43
44
|
respond_to do |format|
|
44
45
|
format.js { render :text => get_upload_text(@upload) }
|
45
46
|
format.json { render :json => basic_uploads_json(@upload) }
|
@@ -74,80 +75,91 @@ class Uploader::UploadsController < ApplicationController
|
|
74
75
|
|
75
76
|
protected
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
78
|
+
def get_upload_text(upload)
|
79
|
+
raise 'implement get_upload_text in your controller'
|
80
|
+
end
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
82
|
+
def set_upload_for_destroy
|
83
|
+
@upload = Upload.find(params[:id])
|
84
|
+
end
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
86
|
+
def permission_denied
|
87
|
+
message = t("uploader.permission_denied")
|
88
|
+
respond_to do |format|
|
89
|
+
format.html do
|
90
|
+
flash[:notice] = message
|
91
|
+
redirect_to get_redirect(:permission_denied)
|
92
|
+
end
|
93
|
+
format.js { render :text => message }
|
94
|
+
format.json { render :json => { :success => false, :message => message } }
|
91
95
|
end
|
92
|
-
format.js { render :text => message }
|
93
|
-
format.json { render :json => { :success => false, :message => message } }
|
94
96
|
end
|
95
|
-
end
|
96
97
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
98
|
+
# override this method in your controller to set the redirect file upload completion
|
99
|
+
# source can be :destroy_success, :create_success, :create_failure, :permission_denied
|
100
|
+
def get_redirect(source)
|
101
|
+
@parent
|
102
|
+
end
|
102
103
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
104
|
+
# Attempts to create an @parent object using params
|
105
|
+
# or the url.
|
106
|
+
def setup_parent(*ignore)
|
107
|
+
@parent = get_parent(ignore)
|
108
|
+
@parent = get_creator if @parent.blank?
|
109
|
+
# if @parent.blank?
|
110
|
+
# render :text => t('muck.engine.missing_parent_error')
|
111
|
+
# return false
|
112
|
+
# end
|
110
113
|
end
|
111
|
-
end
|
112
114
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
115
|
+
# Tries to get parent using parent_type and parent_id from the url.
|
116
|
+
# If that fails and attempt is then made using find_parent
|
117
|
+
# parameters:
|
118
|
+
# ignore: Names to ignore. For example if the url is /foo/1/bar?thing_id=1
|
119
|
+
# you might want to ignore thing_id so pass :thing.
|
120
|
+
def get_parent(*ignore)
|
121
|
+
if params[:parent_type].blank? || params[:parent_id].blank?
|
122
|
+
find_parent(ignore)
|
123
|
+
else
|
124
|
+
klass = params[:parent_type].to_s.constantize
|
125
|
+
klass.find(params[:parent_id])
|
126
|
+
end
|
121
127
|
end
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
128
|
+
|
129
|
+
# Searches the params to try and find an entry ending with _id
|
130
|
+
# ie article_id, user_id, etc. Will return the first value found.
|
131
|
+
# parameters:
|
132
|
+
# ignore: Names to ignore. For example if the url is /foo/1/bar?thing_id=1
|
133
|
+
# you might want to ignore thing_id so pass 'thing' to be ignored.
|
134
|
+
def find_parent(*ignore)
|
135
|
+
ignore.flatten!
|
136
|
+
params.each do |name, value|
|
137
|
+
if name =~ /(.+)_id$/
|
138
|
+
if !ignore.include?($1)
|
139
|
+
return $1.classify.constantize.find(value)
|
140
|
+
end
|
141
|
+
end
|
130
142
|
end
|
143
|
+
nil
|
131
144
|
end
|
132
|
-
nil
|
133
|
-
end
|
134
145
|
|
135
|
-
|
136
|
-
|
137
|
-
|
146
|
+
def filter_permissions
|
147
|
+
unless has_permission_to_upload(current_user, @parent)
|
148
|
+
permission_denied
|
149
|
+
end
|
138
150
|
end
|
139
|
-
end
|
140
151
|
|
141
|
-
|
142
|
-
|
143
|
-
|
152
|
+
def get_creator
|
153
|
+
current_user
|
154
|
+
end
|
144
155
|
|
145
|
-
|
146
|
-
|
147
|
-
|
156
|
+
def has_permission_to_upload(user, upload_parent)
|
157
|
+
return true if upload_parent.blank? # upload will not be connected with a parent object only with the user
|
158
|
+
upload_parent.can_upload?(user)
|
159
|
+
end
|
148
160
|
|
149
|
-
|
150
|
-
|
151
|
-
|
161
|
+
def basic_uploads_json(upload)
|
162
|
+
upload.to_json(:only => [:id], :methods => [:icon, :thumb, :file_name])
|
163
|
+
end
|
152
164
|
|
153
165
|
end
|
@@ -25,7 +25,7 @@
|
|
25
25
|
|
26
26
|
var <%=container_prefix%>swfu;
|
27
27
|
|
28
|
-
|
28
|
+
window.onload = function () {
|
29
29
|
var settings = {
|
30
30
|
|
31
31
|
flash_url : '/swf/swfupload.swf',
|
@@ -76,7 +76,7 @@
|
|
76
76
|
};
|
77
77
|
|
78
78
|
<%=container_prefix%>swfu = new SWFUpload(settings);
|
79
|
-
}
|
79
|
+
};
|
80
80
|
|
81
81
|
</script>
|
82
82
|
<% end -%>
|
@@ -14,7 +14,11 @@ module ActiveRecord
|
|
14
14
|
# :url => "/uploads/:class/:id/:style_:basename.:extension",
|
15
15
|
# :path => ":rails_root/public/uploads/:class/:id/:style_:basename.:extension",
|
16
16
|
# :styles => { :icon => "30x30!", :thumb => "100>", :small => "150>", :medium => "300>", :large => "660>"},
|
17
|
-
# :default_url => "/images/profile_default.jpg" }
|
17
|
+
# :default_url => "/images/profile_default.jpg" },
|
18
|
+
# :disable_halt_nonimage_processing => false
|
19
|
+
#
|
20
|
+
# disable_halt_nonimage_processing - By default all post processing is turned off for non image files. This is useful if you want to setup styles to generate thumbnails for
|
21
|
+
# images but don't want the default Geometry processor to die on non-image files.
|
18
22
|
def acts_as_uploader(options)
|
19
23
|
|
20
24
|
#Named scopes
|
@@ -26,6 +30,7 @@ module ActiveRecord
|
|
26
30
|
named_scope :documents, :conditions => "local_content_type IN (#{(Uploader::MimeTypeGroups::WORD_TYPES + Uploader::MimeTypeGroups::EXCEL_TYPES + Uploader::MimeTypeGroups::PDF_TYPES).collect{|type| "'#{type}'"}.join(',')})"
|
27
31
|
named_scope :files, :conditions => "local_content_type NOT IN (#{Uploader::MimeTypeGroups::IMAGE_TYPES.collect{|type| "'#{type}'"}.join(',')})"
|
28
32
|
named_scope :since, lambda { |*args| { :conditions => ["created_at > ?", (args.first || 7.days.ago.to_s(:db)) ]} }
|
33
|
+
named_scope :created_by, lambda { |*args| { :conditions => ["creator_id = ?", (args.first) ]} }
|
29
34
|
named_scope :pending_s3_migration, lambda { { :conditions => ["remote_file_name IS NULL AND created_at <= ?", 20.minutes.ago.to_s(:db)], :order => 'created_at DESC' } }
|
30
35
|
|
31
36
|
# Paperclip
|
@@ -40,6 +45,7 @@ module ActiveRecord
|
|
40
45
|
class_eval <<-EOV
|
41
46
|
|
42
47
|
before_post_process :transliterate_file_name
|
48
|
+
before_post_process :halt_nonimage_processing unless options[:disable_halt_nonimage_processing]
|
43
49
|
before_create :add_width_and_height
|
44
50
|
|
45
51
|
# prevents a user from submitting a crafted form that bypasses activation
|
@@ -144,6 +150,13 @@ module ActiveRecord
|
|
144
150
|
end
|
145
151
|
end
|
146
152
|
|
153
|
+
# Only works for images
|
154
|
+
def thumb
|
155
|
+
if self.is_image?
|
156
|
+
self.file.url(:thumb)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
147
160
|
def display_name
|
148
161
|
CGI::escapeHTML(self.local_file_name)
|
149
162
|
end
|
@@ -224,6 +237,12 @@ module ActiveRecord
|
|
224
237
|
end
|
225
238
|
end
|
226
239
|
|
240
|
+
def halt_nonimage_processing
|
241
|
+
if !self.is_image? && self.local.options[:styles]
|
242
|
+
return false
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
227
246
|
end
|
228
247
|
end
|
229
248
|
end
|
Binary file
|
@@ -50,7 +50,7 @@ SWFUpload.prototype.initSWFUpload = function (settings) {
|
|
50
50
|
/* *************** */
|
51
51
|
SWFUpload.instances = {};
|
52
52
|
SWFUpload.movieCount = 0;
|
53
|
-
SWFUpload.version = "2.2.0
|
53
|
+
SWFUpload.version = "2.2.0 2009-03-25";
|
54
54
|
SWFUpload.QUEUE_ERROR = {
|
55
55
|
QUEUE_LIMIT_EXCEEDED : -100,
|
56
56
|
FILE_EXCEEDS_SIZE_LIMIT : -110,
|
@@ -91,6 +91,27 @@ SWFUpload.WINDOW_MODE = {
|
|
91
91
|
OPAQUE : "opaque"
|
92
92
|
};
|
93
93
|
|
94
|
+
// Private: takes a URL, determines if it is relative and converts to an absolute URL
|
95
|
+
// using the current site. Only processes the URL if it can, otherwise returns the URL untouched
|
96
|
+
SWFUpload.completeURL = function(url) {
|
97
|
+
if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) {
|
98
|
+
return url;
|
99
|
+
}
|
100
|
+
|
101
|
+
var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : "");
|
102
|
+
|
103
|
+
var indexSlash = window.location.pathname.lastIndexOf("/");
|
104
|
+
if (indexSlash <= 0) {
|
105
|
+
path = "/";
|
106
|
+
} else {
|
107
|
+
path = window.location.pathname.substr(0, indexSlash) + "/";
|
108
|
+
}
|
109
|
+
|
110
|
+
return /*currentURL +*/ path + url;
|
111
|
+
|
112
|
+
};
|
113
|
+
|
114
|
+
|
94
115
|
/* ******************** */
|
95
116
|
/* Instance Members */
|
96
117
|
/* ******************** */
|
@@ -104,11 +125,13 @@ SWFUpload.prototype.initSettings = function () {
|
|
104
125
|
|
105
126
|
// Upload backend settings
|
106
127
|
this.ensureDefault("upload_url", "");
|
128
|
+
this.ensureDefault("preserve_relative_urls", false);
|
107
129
|
this.ensureDefault("file_post_name", "Filedata");
|
108
130
|
this.ensureDefault("post_params", {});
|
109
131
|
this.ensureDefault("use_query_string", false);
|
110
132
|
this.ensureDefault("requeue_on_error", false);
|
111
133
|
this.ensureDefault("http_success", []);
|
134
|
+
this.ensureDefault("assume_success_timeout", 0);
|
112
135
|
|
113
136
|
// File Settings
|
114
137
|
this.ensureDefault("file_types", "*.*");
|
@@ -131,7 +154,8 @@ SWFUpload.prototype.initSettings = function () {
|
|
131
154
|
this.ensureDefault("button_text_left_padding", 0);
|
132
155
|
this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
|
133
156
|
this.ensureDefault("button_disabled", false);
|
134
|
-
this.ensureDefault("button_placeholder_id",
|
157
|
+
this.ensureDefault("button_placeholder_id", "");
|
158
|
+
this.ensureDefault("button_placeholder", null);
|
135
159
|
this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
|
136
160
|
this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
|
137
161
|
|
@@ -161,57 +185,21 @@ SWFUpload.prototype.initSettings = function () {
|
|
161
185
|
this.customSettings = this.settings.custom_settings;
|
162
186
|
|
163
187
|
// Update the flash url if needed
|
164
|
-
if (this.settings.prevent_swf_caching) {
|
165
|
-
this.settings.flash_url = this.settings.flash_url + "?
|
188
|
+
if (!!this.settings.prevent_swf_caching) {
|
189
|
+
this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime();
|
166
190
|
}
|
167
191
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
if (this.settings.button_placeholder_id !== "") {
|
173
|
-
this.replaceWithFlash();
|
174
|
-
} else {
|
175
|
-
this.appendFlash();
|
192
|
+
if (!this.settings.preserve_relative_urls) {
|
193
|
+
//this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url); // Don't need to do this one since flash doesn't look at it
|
194
|
+
this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);
|
195
|
+
this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url);
|
176
196
|
}
|
177
|
-
};
|
178
|
-
|
179
|
-
// Private: appendFlash gets the HTML tag for the Flash
|
180
|
-
// It then appends the flash to the body
|
181
|
-
SWFUpload.prototype.appendFlash = function () {
|
182
|
-
var targetElement, container;
|
183
|
-
|
184
|
-
// Make sure an element with the ID we are going to use doesn't already exist
|
185
|
-
if (document.getElementById(this.movieName) !== null) {
|
186
|
-
throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
|
187
|
-
}
|
188
|
-
|
189
|
-
// Get the body tag where we will be adding the flash movie
|
190
|
-
targetElement = document.getElementsByTagName("body")[0];
|
191
|
-
|
192
|
-
if (targetElement == undefined) {
|
193
|
-
throw "Could not find the 'body' element.";
|
194
|
-
}
|
195
|
-
|
196
|
-
// Append the container and load the flash
|
197
|
-
container = document.createElement("div");
|
198
|
-
container.style.width = "1px";
|
199
|
-
container.style.height = "1px";
|
200
|
-
container.style.overflow = "hidden";
|
201
|
-
|
202
|
-
targetElement.appendChild(container);
|
203
|
-
container.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
|
204
|
-
|
205
|
-
// Fix IE Flash/Form bug
|
206
|
-
if (window[this.movieName] == undefined) {
|
207
|
-
window[this.movieName] = this.getMovieElement();
|
208
|
-
}
|
209
|
-
|
210
197
|
|
198
|
+
delete this.ensureDefault;
|
211
199
|
};
|
212
200
|
|
213
|
-
// Private:
|
214
|
-
SWFUpload.prototype.
|
201
|
+
// Private: loadFlash replaces the button_placeholder element with the flash movie.
|
202
|
+
SWFUpload.prototype.loadFlash = function () {
|
215
203
|
var targetElement, tempParent;
|
216
204
|
|
217
205
|
// Make sure an element with the ID we are going to use doesn't already exist
|
@@ -220,10 +208,10 @@ SWFUpload.prototype.replaceWithFlash = function () {
|
|
220
208
|
}
|
221
209
|
|
222
210
|
// Get the element where we will be placing the flash movie
|
223
|
-
targetElement = document.getElementById(this.settings.button_placeholder_id);
|
211
|
+
targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;
|
224
212
|
|
225
213
|
if (targetElement == undefined) {
|
226
|
-
throw "Could not find the placeholder element.
|
214
|
+
throw "Could not find the placeholder element: " + this.settings.button_placeholder_id;
|
227
215
|
}
|
228
216
|
|
229
217
|
// Append the container and load the flash
|
@@ -242,7 +230,7 @@ SWFUpload.prototype.replaceWithFlash = function () {
|
|
242
230
|
SWFUpload.prototype.getFlashHTML = function () {
|
243
231
|
// Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
|
244
232
|
return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
|
245
|
-
'<param name="wmode" value="', this.settings.button_window_mode
|
233
|
+
'<param name="wmode" value="', this.settings.button_window_mode, '" />',
|
246
234
|
'<param name="movie" value="', this.settings.flash_url, '" />',
|
247
235
|
'<param name="quality" value="high" />',
|
248
236
|
'<param name="menu" value="false" />',
|
@@ -264,6 +252,7 @@ SWFUpload.prototype.getFlashVars = function () {
|
|
264
252
|
"&useQueryString=", encodeURIComponent(this.settings.use_query_string),
|
265
253
|
"&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
|
266
254
|
"&httpSuccess=", encodeURIComponent(httpSuccessString),
|
255
|
+
"&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
|
267
256
|
"&params=", encodeURIComponent(paramString),
|
268
257
|
"&filePostName=", encodeURIComponent(this.settings.file_post_name),
|
269
258
|
"&fileTypes=", encodeURIComponent(this.settings.file_types),
|
@@ -325,11 +314,12 @@ SWFUpload.prototype.destroy = function () {
|
|
325
314
|
// Make sure Flash is done before we try to remove it
|
326
315
|
this.cancelUpload(null, false);
|
327
316
|
|
317
|
+
|
328
318
|
// Remove the SWFUpload DOM nodes
|
329
319
|
var movieElement = null;
|
330
320
|
movieElement = this.getMovieElement();
|
331
321
|
|
332
|
-
if (movieElement) {
|
322
|
+
if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
|
333
323
|
// Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround)
|
334
324
|
for (var i in movieElement) {
|
335
325
|
try {
|
@@ -345,7 +335,6 @@ SWFUpload.prototype.destroy = function () {
|
|
345
335
|
} catch (ex) {}
|
346
336
|
}
|
347
337
|
|
348
|
-
|
349
338
|
// Remove IE form fix reference
|
350
339
|
window[this.movieName] = null;
|
351
340
|
|
@@ -361,11 +350,12 @@ SWFUpload.prototype.destroy = function () {
|
|
361
350
|
|
362
351
|
|
363
352
|
return true;
|
364
|
-
} catch (
|
353
|
+
} catch (ex2) {
|
365
354
|
return false;
|
366
355
|
}
|
367
356
|
};
|
368
357
|
|
358
|
+
|
369
359
|
// Public: displayDebugInfo prints out settings and configuration
|
370
360
|
// information about this SWFUpload instance.
|
371
361
|
// This function (and any references to it) can be deleted when placing
|
@@ -382,6 +372,7 @@ SWFUpload.prototype.displayDebugInfo = function () {
|
|
382
372
|
"\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n",
|
383
373
|
"\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n",
|
384
374
|
"\t", "http_success: ", this.settings.http_success.join(", "), "\n",
|
375
|
+
"\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n",
|
385
376
|
"\t", "file_post_name: ", this.settings.file_post_name, "\n",
|
386
377
|
"\t", "post_params: ", this.settings.post_params.toString(), "\n",
|
387
378
|
"\t", "file_types: ", this.settings.file_types, "\n",
|
@@ -394,6 +385,7 @@ SWFUpload.prototype.displayDebugInfo = function () {
|
|
394
385
|
"\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n",
|
395
386
|
|
396
387
|
"\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n",
|
388
|
+
"\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
|
397
389
|
"\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n",
|
398
390
|
"\t", "button_width: ", this.settings.button_width.toString(), "\n",
|
399
391
|
"\t", "button_height: ", this.settings.button_height.toString(), "\n",
|
@@ -468,7 +460,6 @@ SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
|
|
468
460
|
return returnValue;
|
469
461
|
};
|
470
462
|
|
471
|
-
|
472
463
|
/* *****************************
|
473
464
|
-- Flash control methods --
|
474
465
|
Your UI should use these
|
@@ -636,6 +627,11 @@ SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
|
|
636
627
|
this.callFlash("SetHTTPSuccess", [http_status_codes]);
|
637
628
|
};
|
638
629
|
|
630
|
+
// Public: setHTTPSuccess changes the http_success setting
|
631
|
+
SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
|
632
|
+
this.settings.assume_success_timeout = timeout_seconds;
|
633
|
+
this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
|
634
|
+
};
|
639
635
|
|
640
636
|
// Public: setDebugEnabled changes the debug_enabled setting
|
641
637
|
SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
|
@@ -776,24 +772,63 @@ SWFUpload.prototype.unescapeFilePostParams = function (file) {
|
|
776
772
|
return file;
|
777
773
|
};
|
778
774
|
|
775
|
+
// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working)
|
776
|
+
SWFUpload.prototype.testExternalInterface = function () {
|
777
|
+
try {
|
778
|
+
return this.callFlash("TestExternalInterface");
|
779
|
+
} catch (ex) {
|
780
|
+
return false;
|
781
|
+
}
|
782
|
+
};
|
783
|
+
|
784
|
+
// Private: This event is called by Flash when it has finished loading. Don't modify this.
|
785
|
+
// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded.
|
779
786
|
SWFUpload.prototype.flashReady = function () {
|
780
787
|
// Check that the movie element is loaded correctly with its ExternalInterface methods defined
|
781
788
|
var movieElement = this.getMovieElement();
|
782
789
|
|
790
|
+
if (!movieElement) {
|
791
|
+
this.debug("Flash called back ready but the flash movie can't be found.");
|
792
|
+
return;
|
793
|
+
}
|
794
|
+
|
795
|
+
this.cleanUp(movieElement);
|
796
|
+
|
797
|
+
this.queueEvent("swfupload_loaded_handler");
|
798
|
+
};
|
799
|
+
|
800
|
+
// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE.
|
801
|
+
// This function is called by Flash each time the ExternalInterface functions are created.
|
802
|
+
SWFUpload.prototype.cleanUp = function (movieElement) {
|
783
803
|
// Pro-actively unhook all the Flash functions
|
784
|
-
|
785
|
-
this.
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
movieElement[key]
|
804
|
+
try {
|
805
|
+
if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
|
806
|
+
this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");
|
807
|
+
for (var key in movieElement) {
|
808
|
+
try {
|
809
|
+
if (typeof(movieElement[key]) === "function") {
|
810
|
+
movieElement[key] = null;
|
811
|
+
}
|
812
|
+
} catch (ex) {
|
790
813
|
}
|
791
|
-
} catch (ex) {
|
792
814
|
}
|
793
815
|
}
|
794
|
-
}
|
816
|
+
} catch (ex1) {
|
795
817
|
|
796
|
-
|
818
|
+
}
|
819
|
+
|
820
|
+
// Fix Flashes own cleanup code so if the SWFMovie was removed from the page
|
821
|
+
// it doesn't display errors.
|
822
|
+
window["__flash__removeCallback"] = function (instance, name) {
|
823
|
+
try {
|
824
|
+
if (instance) {
|
825
|
+
instance[name] = null;
|
826
|
+
}
|
827
|
+
} catch (flashEx) {
|
828
|
+
|
829
|
+
}
|
830
|
+
};
|
831
|
+
|
797
832
|
};
|
798
833
|
|
799
834
|
|
@@ -818,8 +853,8 @@ SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
|
|
818
853
|
|
819
854
|
/* Called after the file dialog has closed and the selected files have been queued.
|
820
855
|
You could call startUpload here if you want the queued files to begin uploading immediately. */
|
821
|
-
SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued) {
|
822
|
-
this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued]);
|
856
|
+
SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
|
857
|
+
this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
|
823
858
|
};
|
824
859
|
|
825
860
|
SWFUpload.prototype.uploadStart = function (file) {
|
@@ -859,9 +894,9 @@ SWFUpload.prototype.uploadError = function (file, errorCode, message) {
|
|
859
894
|
this.queueEvent("upload_error_handler", [file, errorCode, message]);
|
860
895
|
};
|
861
896
|
|
862
|
-
SWFUpload.prototype.uploadSuccess = function (file, serverData) {
|
897
|
+
SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
|
863
898
|
file = this.unescapeFilePostParams(file);
|
864
|
-
this.queueEvent("upload_success_handler", [file, serverData]);
|
899
|
+
this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
|
865
900
|
};
|
866
901
|
|
867
902
|
SWFUpload.prototype.uploadComplete = function (file) {
|