uploader 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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) {
|