~canonical-sysadmins/wordpress/4.7.2

« back to all changes in this revision

Viewing changes to wp-includes/js/swfupload/swfupload.js

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
 
3
 *
 
4
 * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/,  http://www.vinterwebb.se/
 
5
 *
 
6
 * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz�n and Mammon Media and is released under the MIT License:
 
7
 * http://www.opensource.org/licenses/mit-license.php
 
8
 *
 
9
 * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
 
10
 * http://www.opensource.org/licenses/mit-license.php
 
11
 *
 
12
 */
 
13
 
 
14
 
 
15
/* ******************* */
 
16
/* Constructor & Init  */
 
17
/* ******************* */
 
18
var SWFUpload;
 
19
 
 
20
if (SWFUpload == undefined) {
 
21
        SWFUpload = function (settings) {
 
22
                this.initSWFUpload(settings);
 
23
        };
 
24
}
 
25
 
 
26
SWFUpload.prototype.initSWFUpload = function (settings) {
 
27
        try {
 
28
                this.customSettings = {};       // A container where developers can place their own settings associated with this instance.
 
29
                this.settings = settings;
 
30
                this.eventQueue = [];
 
31
                this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
 
32
                this.movieElement = null;
 
33
 
 
34
 
 
35
                // Setup global control tracking
 
36
                SWFUpload.instances[this.movieName] = this;
 
37
 
 
38
                // Load the settings.  Load the Flash movie.
 
39
                this.initSettings();
 
40
                this.loadFlash();
 
41
                this.displayDebugInfo();
 
42
        } catch (ex) {
 
43
                delete SWFUpload.instances[this.movieName];
 
44
                throw ex;
 
45
        }
 
46
};
 
47
 
 
48
/* *************** */
 
49
/* Static Members  */
 
50
/* *************** */
 
51
SWFUpload.instances = {};
 
52
SWFUpload.movieCount = 0;
 
53
SWFUpload.version = "2.2.0 2009-03-25";
 
54
SWFUpload.QUEUE_ERROR = {
 
55
        QUEUE_LIMIT_EXCEEDED                    : -100,
 
56
        FILE_EXCEEDS_SIZE_LIMIT                 : -110,
 
57
        ZERO_BYTE_FILE                                  : -120,
 
58
        INVALID_FILETYPE                                : -130
 
59
};
 
60
SWFUpload.UPLOAD_ERROR = {
 
61
        HTTP_ERROR                                              : -200,
 
62
        MISSING_UPLOAD_URL                      : -210,
 
63
        IO_ERROR                                                : -220,
 
64
        SECURITY_ERROR                                  : -230,
 
65
        UPLOAD_LIMIT_EXCEEDED                   : -240,
 
66
        UPLOAD_FAILED                                   : -250,
 
67
        SPECIFIED_FILE_ID_NOT_FOUND             : -260,
 
68
        FILE_VALIDATION_FAILED                  : -270,
 
69
        FILE_CANCELLED                                  : -280,
 
70
        UPLOAD_STOPPED                                  : -290
 
71
};
 
72
SWFUpload.FILE_STATUS = {
 
73
        QUEUED           : -1,
 
74
        IN_PROGRESS      : -2,
 
75
        ERROR            : -3,
 
76
        COMPLETE         : -4,
 
77
        CANCELLED        : -5
 
78
};
 
79
SWFUpload.BUTTON_ACTION = {
 
80
        SELECT_FILE  : -100,
 
81
        SELECT_FILES : -110,
 
82
        START_UPLOAD : -120
 
83
};
 
84
SWFUpload.CURSOR = {
 
85
        ARROW : -1,
 
86
        HAND : -2
 
87
};
 
88
SWFUpload.WINDOW_MODE = {
 
89
        WINDOW : "window",
 
90
        TRANSPARENT : "transparent",
 
91
        OPAQUE : "opaque"
 
92
};
 
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
 
 
115
/* ******************** */
 
116
/* Instance Members  */
 
117
/* ******************** */
 
118
 
 
119
// Private: initSettings ensures that all the
 
120
// settings are set, getting a default value if one was not assigned.
 
121
SWFUpload.prototype.initSettings = function () {
 
122
        this.ensureDefault = function (settingName, defaultValue) {
 
123
                this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
 
124
        };
 
125
        
 
126
        // Upload backend settings
 
127
        this.ensureDefault("upload_url", "");
 
128
        this.ensureDefault("preserve_relative_urls", false);
 
129
        this.ensureDefault("file_post_name", "Filedata");
 
130
        this.ensureDefault("post_params", {});
 
131
        this.ensureDefault("use_query_string", false);
 
132
        this.ensureDefault("requeue_on_error", false);
 
133
        this.ensureDefault("http_success", []);
 
134
        this.ensureDefault("assume_success_timeout", 0);
 
135
        
 
136
        // File Settings
 
137
        this.ensureDefault("file_types", "*.*");
 
138
        this.ensureDefault("file_types_description", "All Files");
 
139
        this.ensureDefault("file_size_limit", 0);       // Default zero means "unlimited"
 
140
        this.ensureDefault("file_upload_limit", 0);
 
141
        this.ensureDefault("file_queue_limit", 0);
 
142
 
 
143
        // Flash Settings
 
144
        this.ensureDefault("flash_url", "swfupload.swf");
 
145
        this.ensureDefault("prevent_swf_caching", true);
 
146
        
 
147
        // Button Settings
 
148
        this.ensureDefault("button_image_url", "");
 
149
        this.ensureDefault("button_width", 1);
 
150
        this.ensureDefault("button_height", 1);
 
151
        this.ensureDefault("button_text", "");
 
152
        this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
 
153
        this.ensureDefault("button_text_top_padding", 0);
 
154
        this.ensureDefault("button_text_left_padding", 0);
 
155
        this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
 
156
        this.ensureDefault("button_disabled", false);
 
157
        this.ensureDefault("button_placeholder_id", "");
 
158
        this.ensureDefault("button_placeholder", null);
 
159
        this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
 
160
        this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
 
161
        
 
162
        // Debug Settings
 
163
        this.ensureDefault("debug", false);
 
164
        this.settings.debug_enabled = this.settings.debug;      // Here to maintain v2 API
 
165
        
 
166
        // Event Handlers
 
167
        this.settings.return_upload_start_handler = this.returnUploadStart;
 
168
        this.ensureDefault("swfupload_loaded_handler", null);
 
169
        this.ensureDefault("file_dialog_start_handler", null);
 
170
        this.ensureDefault("file_queued_handler", null);
 
171
        this.ensureDefault("file_queue_error_handler", null);
 
172
        this.ensureDefault("file_dialog_complete_handler", null);
 
173
        
 
174
        this.ensureDefault("upload_start_handler", null);
 
175
        this.ensureDefault("upload_progress_handler", null);
 
176
        this.ensureDefault("upload_error_handler", null);
 
177
        this.ensureDefault("upload_success_handler", null);
 
178
        this.ensureDefault("upload_complete_handler", null);
 
179
        
 
180
        this.ensureDefault("debug_handler", this.debugMessage);
 
181
 
 
182
        this.ensureDefault("custom_settings", {});
 
183
 
 
184
        // Other settings
 
185
        this.customSettings = this.settings.custom_settings;
 
186
        
 
187
        // Update the flash url if needed
 
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();
 
190
        }
 
191
        
 
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);
 
196
        }
 
197
        
 
198
        delete this.ensureDefault;
 
199
};
 
200
 
 
201
// Private: loadFlash replaces the button_placeholder element with the flash movie.
 
202
SWFUpload.prototype.loadFlash = function () {
 
203
        var targetElement, tempParent;
 
204
 
 
205
        // Make sure an element with the ID we are going to use doesn't already exist
 
206
        if (document.getElementById(this.movieName) !== null) {
 
207
                throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
 
208
        }
 
209
 
 
210
        // Get the element where we will be placing the flash movie
 
211
        targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;
 
212
 
 
213
        if (targetElement == undefined) {
 
214
                throw "Could not find the placeholder element: " + this.settings.button_placeholder_id;
 
215
        }
 
216
 
 
217
        // Append the container and load the flash
 
218
        tempParent = document.createElement("div");
 
219
        tempParent.innerHTML = this.getFlashHTML();     // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
 
220
        targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
 
221
 
 
222
        // Fix IE Flash/Form bug
 
223
        if (window[this.movieName] == undefined) {
 
224
                window[this.movieName] = this.getMovieElement();
 
225
        }
 
226
        
 
227
};
 
228
 
 
229
// Private: getFlashHTML generates the object tag needed to embed the flash in to the document
 
230
SWFUpload.prototype.getFlashHTML = function () {
 
231
        // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
 
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">',
 
233
                                '<param name="wmode" value="', this.settings.button_window_mode, '" />',
 
234
                                '<param name="movie" value="', this.settings.flash_url, '" />',
 
235
                                '<param name="quality" value="high" />',
 
236
                                '<param name="menu" value="false" />',
 
237
                                '<param name="allowScriptAccess" value="always" />',
 
238
                                '<param name="flashvars" value="' + this.getFlashVars() + '" />',
 
239
                                '</object>'].join("");
 
240
};
 
241
 
 
242
// Private: getFlashVars builds the parameter string that will be passed
 
243
// to flash in the flashvars param.
 
244
SWFUpload.prototype.getFlashVars = function () {
 
245
        // Build a string from the post param object
 
246
        var paramString = this.buildParamString();
 
247
        var httpSuccessString = this.settings.http_success.join(",");
 
248
        
 
249
        // Build the parameter string
 
250
        return ["movieName=", encodeURIComponent(this.movieName),
 
251
                        "&amp;uploadURL=", encodeURIComponent(this.settings.upload_url),
 
252
                        "&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string),
 
253
                        "&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
 
254
                        "&amp;httpSuccess=", encodeURIComponent(httpSuccessString),
 
255
                        "&amp;assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
 
256
                        "&amp;params=", encodeURIComponent(paramString),
 
257
                        "&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
 
258
                        "&amp;fileTypes=", encodeURIComponent(this.settings.file_types),
 
259
                        "&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
 
260
                        "&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
 
261
                        "&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
 
262
                        "&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
 
263
                        "&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
 
264
                        "&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
 
265
                        "&amp;buttonWidth=", encodeURIComponent(this.settings.button_width),
 
266
                        "&amp;buttonHeight=", encodeURIComponent(this.settings.button_height),
 
267
                        "&amp;buttonText=", encodeURIComponent(this.settings.button_text),
 
268
                        "&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
 
269
                        "&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
 
270
                        "&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
 
271
                        "&amp;buttonAction=", encodeURIComponent(this.settings.button_action),
 
272
                        "&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled),
 
273
                        "&amp;buttonCursor=", encodeURIComponent(this.settings.button_cursor)
 
274
                ].join("");
 
275
};
 
276
 
 
277
// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload
 
278
// The element is cached after the first lookup
 
279
SWFUpload.prototype.getMovieElement = function () {
 
280
        if (this.movieElement == undefined) {
 
281
                this.movieElement = document.getElementById(this.movieName);
 
282
        }
 
283
 
 
284
        if (this.movieElement === null) {
 
285
                throw "Could not find Flash element";
 
286
        }
 
287
        
 
288
        return this.movieElement;
 
289
};
 
290
 
 
291
// Private: buildParamString takes the name/value pairs in the post_params setting object
 
292
// and joins them up in to a string formatted "name=value&amp;name=value"
 
293
SWFUpload.prototype.buildParamString = function () {
 
294
        var postParams = this.settings.post_params; 
 
295
        var paramStringPairs = [];
 
296
 
 
297
        if (typeof(postParams) === "object") {
 
298
                for (var name in postParams) {
 
299
                        if (postParams.hasOwnProperty(name)) {
 
300
                                paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
 
301
                        }
 
302
                }
 
303
        }
 
304
 
 
305
        return paramStringPairs.join("&amp;");
 
306
};
 
307
 
 
308
// Public: Used to remove a SWFUpload instance from the page. This method strives to remove
 
309
// all references to the SWF, and other objects so memory is properly freed.
 
310
// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
 
311
// Credits: Major improvements provided by steffen
 
312
SWFUpload.prototype.destroy = function () {
 
313
        try {
 
314
                // Make sure Flash is done before we try to remove it
 
315
                this.cancelUpload(null, false);
 
316
                
 
317
 
 
318
                // Remove the SWFUpload DOM nodes
 
319
                var movieElement = null;
 
320
                movieElement = this.getMovieElement();
 
321
                
 
322
                if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
 
323
                        // Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround)
 
324
                        for (var i in movieElement) {
 
325
                                try {
 
326
                                        if (typeof(movieElement[i]) === "function") {
 
327
                                                movieElement[i] = null;
 
328
                                        }
 
329
                                } catch (ex1) {}
 
330
                        }
 
331
 
 
332
                        // Remove the Movie Element from the page
 
333
                        try {
 
334
                                movieElement.parentNode.removeChild(movieElement);
 
335
                        } catch (ex) {}
 
336
                }
 
337
                
 
338
                // Remove IE form fix reference
 
339
                window[this.movieName] = null;
 
340
 
 
341
                // Destroy other references
 
342
                SWFUpload.instances[this.movieName] = null;
 
343
                delete SWFUpload.instances[this.movieName];
 
344
 
 
345
                this.movieElement = null;
 
346
                this.settings = null;
 
347
                this.customSettings = null;
 
348
                this.eventQueue = null;
 
349
                this.movieName = null;
 
350
                
 
351
                
 
352
                return true;
 
353
        } catch (ex2) {
 
354
                return false;
 
355
        }
 
356
};
 
357
 
 
358
 
 
359
// Public: displayDebugInfo prints out settings and configuration
 
360
// information about this SWFUpload instance.
 
361
// This function (and any references to it) can be deleted when placing
 
362
// SWFUpload in production.
 
363
SWFUpload.prototype.displayDebugInfo = function () {
 
364
        this.debug(
 
365
                [
 
366
                        "---SWFUpload Instance Info---\n",
 
367
                        "Version: ", SWFUpload.version, "\n",
 
368
                        "Movie Name: ", this.movieName, "\n",
 
369
                        "Settings:\n",
 
370
                        "\t", "upload_url:               ", this.settings.upload_url, "\n",
 
371
                        "\t", "flash_url:                ", this.settings.flash_url, "\n",
 
372
                        "\t", "use_query_string:         ", this.settings.use_query_string.toString(), "\n",
 
373
                        "\t", "requeue_on_error:         ", this.settings.requeue_on_error.toString(), "\n",
 
374
                        "\t", "http_success:             ", this.settings.http_success.join(", "), "\n",
 
375
                        "\t", "assume_success_timeout:   ", this.settings.assume_success_timeout, "\n",
 
376
                        "\t", "file_post_name:           ", this.settings.file_post_name, "\n",
 
377
                        "\t", "post_params:              ", this.settings.post_params.toString(), "\n",
 
378
                        "\t", "file_types:               ", this.settings.file_types, "\n",
 
379
                        "\t", "file_types_description:   ", this.settings.file_types_description, "\n",
 
380
                        "\t", "file_size_limit:          ", this.settings.file_size_limit, "\n",
 
381
                        "\t", "file_upload_limit:        ", this.settings.file_upload_limit, "\n",
 
382
                        "\t", "file_queue_limit:         ", this.settings.file_queue_limit, "\n",
 
383
                        "\t", "debug:                    ", this.settings.debug.toString(), "\n",
 
384
 
 
385
                        "\t", "prevent_swf_caching:      ", this.settings.prevent_swf_caching.toString(), "\n",
 
386
 
 
387
                        "\t", "button_placeholder_id:    ", this.settings.button_placeholder_id.toString(), "\n",
 
388
                        "\t", "button_placeholder:       ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
 
389
                        "\t", "button_image_url:         ", this.settings.button_image_url.toString(), "\n",
 
390
                        "\t", "button_width:             ", this.settings.button_width.toString(), "\n",
 
391
                        "\t", "button_height:            ", this.settings.button_height.toString(), "\n",
 
392
                        "\t", "button_text:              ", this.settings.button_text.toString(), "\n",
 
393
                        "\t", "button_text_style:        ", this.settings.button_text_style.toString(), "\n",
 
394
                        "\t", "button_text_top_padding:  ", this.settings.button_text_top_padding.toString(), "\n",
 
395
                        "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
 
396
                        "\t", "button_action:            ", this.settings.button_action.toString(), "\n",
 
397
                        "\t", "button_disabled:          ", this.settings.button_disabled.toString(), "\n",
 
398
 
 
399
                        "\t", "custom_settings:          ", this.settings.custom_settings.toString(), "\n",
 
400
                        "Event Handlers:\n",
 
401
                        "\t", "swfupload_loaded_handler assigned:  ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n",
 
402
                        "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n",
 
403
                        "\t", "file_queued_handler assigned:       ", (typeof this.settings.file_queued_handler === "function").toString(), "\n",
 
404
                        "\t", "file_queue_error_handler assigned:  ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n",
 
405
                        "\t", "upload_start_handler assigned:      ", (typeof this.settings.upload_start_handler === "function").toString(), "\n",
 
406
                        "\t", "upload_progress_handler assigned:   ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n",
 
407
                        "\t", "upload_error_handler assigned:      ", (typeof this.settings.upload_error_handler === "function").toString(), "\n",
 
408
                        "\t", "upload_success_handler assigned:    ", (typeof this.settings.upload_success_handler === "function").toString(), "\n",
 
409
                        "\t", "upload_complete_handler assigned:   ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n",
 
410
                        "\t", "debug_handler assigned:             ", (typeof this.settings.debug_handler === "function").toString(), "\n"
 
411
                ].join("")
 
412
        );
 
413
};
 
414
 
 
415
/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
 
416
        the maintain v2 API compatibility
 
417
*/
 
418
// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
 
419
SWFUpload.prototype.addSetting = function (name, value, default_value) {
 
420
    if (value == undefined) {
 
421
        return (this.settings[name] = default_value);
 
422
    } else {
 
423
        return (this.settings[name] = value);
 
424
        }
 
425
};
 
426
 
 
427
// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
 
428
SWFUpload.prototype.getSetting = function (name) {
 
429
    if (this.settings[name] != undefined) {
 
430
        return this.settings[name];
 
431
        }
 
432
 
 
433
    return "";
 
434
};
 
435
 
 
436
 
 
437
 
 
438
// Private: callFlash handles function calls made to the Flash element.
 
439
// Calls are made with a setTimeout for some functions to work around
 
440
// bugs in the ExternalInterface library.
 
441
SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
 
442
        argumentArray = argumentArray || [];
 
443
        
 
444
        var movieElement = this.getMovieElement();
 
445
        var returnValue, returnString;
 
446
 
 
447
        // Flash's method if calling ExternalInterface methods (code adapted from MooTools).
 
448
        try {
 
449
                returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
 
450
                returnValue = eval(returnString);
 
451
        } catch (ex) {
 
452
                throw "Call to " + functionName + " failed";
 
453
        }
 
454
        
 
455
        // Unescape file post param values
 
456
        if (returnValue != undefined && typeof returnValue.post === "object") {
 
457
                returnValue = this.unescapeFilePostParams(returnValue);
 
458
        }
 
459
 
 
460
        return returnValue;
 
461
};
 
462
 
 
463
/* *****************************
 
464
        -- Flash control methods --
 
465
        Your UI should use these
 
466
        to operate SWFUpload
 
467
   ***************************** */
 
468
 
 
469
// WARNING: this function does not work in Flash Player 10
 
470
// Public: selectFile causes a File Selection Dialog window to appear.  This
 
471
// dialog only allows 1 file to be selected.
 
472
SWFUpload.prototype.selectFile = function () {
 
473
        this.callFlash("SelectFile");
 
474
};
 
475
 
 
476
// WARNING: this function does not work in Flash Player 10
 
477
// Public: selectFiles causes a File Selection Dialog window to appear/ This
 
478
// dialog allows the user to select any number of files
 
479
// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
 
480
// If the selection name length is too long the dialog will fail in an unpredictable manner.  There is no work-around
 
481
// for this bug.
 
482
SWFUpload.prototype.selectFiles = function () {
 
483
        this.callFlash("SelectFiles");
 
484
};
 
485
 
 
486
 
 
487
// Public: startUpload starts uploading the first file in the queue unless
 
488
// the optional parameter 'fileID' specifies the ID 
 
489
SWFUpload.prototype.startUpload = function (fileID) {
 
490
        this.callFlash("StartUpload", [fileID]);
 
491
};
 
492
 
 
493
// Public: cancelUpload cancels any queued file.  The fileID parameter may be the file ID or index.
 
494
// If you do not specify a fileID the current uploading file or first file in the queue is cancelled.
 
495
// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter.
 
496
SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
 
497
        if (triggerErrorEvent !== false) {
 
498
                triggerErrorEvent = true;
 
499
        }
 
500
        this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
 
501
};
 
502
 
 
503
// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
 
504
// If nothing is currently uploading then nothing happens.
 
505
SWFUpload.prototype.stopUpload = function () {
 
506
        this.callFlash("StopUpload");
 
507
};
 
508
 
 
509
/* ************************
 
510
 * Settings methods
 
511
 *   These methods change the SWFUpload settings.
 
512
 *   SWFUpload settings should not be changed directly on the settings object
 
513
 *   since many of the settings need to be passed to Flash in order to take
 
514
 *   effect.
 
515
 * *********************** */
 
516
 
 
517
// Public: getStats gets the file statistics object.
 
518
SWFUpload.prototype.getStats = function () {
 
519
        return this.callFlash("GetStats");
 
520
};
 
521
 
 
522
// Public: setStats changes the SWFUpload statistics.  You shouldn't need to 
 
523
// change the statistics but you can.  Changing the statistics does not
 
524
// affect SWFUpload accept for the successful_uploads count which is used
 
525
// by the upload_limit setting to determine how many files the user may upload.
 
526
SWFUpload.prototype.setStats = function (statsObject) {
 
527
        this.callFlash("SetStats", [statsObject]);
 
528
};
 
529
 
 
530
// Public: getFile retrieves a File object by ID or Index.  If the file is
 
531
// not found then 'null' is returned.
 
532
SWFUpload.prototype.getFile = function (fileID) {
 
533
        if (typeof(fileID) === "number") {
 
534
                return this.callFlash("GetFileByIndex", [fileID]);
 
535
        } else {
 
536
                return this.callFlash("GetFile", [fileID]);
 
537
        }
 
538
};
 
539
 
 
540
// Public: addFileParam sets a name/value pair that will be posted with the
 
541
// file specified by the Files ID.  If the name already exists then the
 
542
// exiting value will be overwritten.
 
543
SWFUpload.prototype.addFileParam = function (fileID, name, value) {
 
544
        return this.callFlash("AddFileParam", [fileID, name, value]);
 
545
};
 
546
 
 
547
// Public: removeFileParam removes a previously set (by addFileParam) name/value
 
548
// pair from the specified file.
 
549
SWFUpload.prototype.removeFileParam = function (fileID, name) {
 
550
        this.callFlash("RemoveFileParam", [fileID, name]);
 
551
};
 
552
 
 
553
// Public: setUploadUrl changes the upload_url setting.
 
554
SWFUpload.prototype.setUploadURL = function (url) {
 
555
        this.settings.upload_url = url.toString();
 
556
        this.callFlash("SetUploadURL", [url]);
 
557
};
 
558
 
 
559
// Public: setPostParams changes the post_params setting
 
560
SWFUpload.prototype.setPostParams = function (paramsObject) {
 
561
        this.settings.post_params = paramsObject;
 
562
        this.callFlash("SetPostParams", [paramsObject]);
 
563
};
 
564
 
 
565
// Public: addPostParam adds post name/value pair.  Each name can have only one value.
 
566
SWFUpload.prototype.addPostParam = function (name, value) {
 
567
        this.settings.post_params[name] = value;
 
568
        this.callFlash("SetPostParams", [this.settings.post_params]);
 
569
};
 
570
 
 
571
// Public: removePostParam deletes post name/value pair.
 
572
SWFUpload.prototype.removePostParam = function (name) {
 
573
        delete this.settings.post_params[name];
 
574
        this.callFlash("SetPostParams", [this.settings.post_params]);
 
575
};
 
576
 
 
577
// Public: setFileTypes changes the file_types setting and the file_types_description setting
 
578
SWFUpload.prototype.setFileTypes = function (types, description) {
 
579
        this.settings.file_types = types;
 
580
        this.settings.file_types_description = description;
 
581
        this.callFlash("SetFileTypes", [types, description]);
 
582
};
 
583
 
 
584
// Public: setFileSizeLimit changes the file_size_limit setting
 
585
SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
 
586
        this.settings.file_size_limit = fileSizeLimit;
 
587
        this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
 
588
};
 
589
 
 
590
// Public: setFileUploadLimit changes the file_upload_limit setting
 
591
SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
 
592
        this.settings.file_upload_limit = fileUploadLimit;
 
593
        this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
 
594
};
 
595
 
 
596
// Public: setFileQueueLimit changes the file_queue_limit setting
 
597
SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
 
598
        this.settings.file_queue_limit = fileQueueLimit;
 
599
        this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
 
600
};
 
601
 
 
602
// Public: setFilePostName changes the file_post_name setting
 
603
SWFUpload.prototype.setFilePostName = function (filePostName) {
 
604
        this.settings.file_post_name = filePostName;
 
605
        this.callFlash("SetFilePostName", [filePostName]);
 
606
};
 
607
 
 
608
// Public: setUseQueryString changes the use_query_string setting
 
609
SWFUpload.prototype.setUseQueryString = function (useQueryString) {
 
610
        this.settings.use_query_string = useQueryString;
 
611
        this.callFlash("SetUseQueryString", [useQueryString]);
 
612
};
 
613
 
 
614
// Public: setRequeueOnError changes the requeue_on_error setting
 
615
SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
 
616
        this.settings.requeue_on_error = requeueOnError;
 
617
        this.callFlash("SetRequeueOnError", [requeueOnError]);
 
618
};
 
619
 
 
620
// Public: setHTTPSuccess changes the http_success setting
 
621
SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
 
622
        if (typeof http_status_codes === "string") {
 
623
                http_status_codes = http_status_codes.replace(" ", "").split(",");
 
624
        }
 
625
        
 
626
        this.settings.http_success = http_status_codes;
 
627
        this.callFlash("SetHTTPSuccess", [http_status_codes]);
 
628
};
 
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
};
 
635
 
 
636
// Public: setDebugEnabled changes the debug_enabled setting
 
637
SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
 
638
        this.settings.debug_enabled = debugEnabled;
 
639
        this.callFlash("SetDebugEnabled", [debugEnabled]);
 
640
};
 
641
 
 
642
// Public: setButtonImageURL loads a button image sprite
 
643
SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
 
644
        if (buttonImageURL == undefined) {
 
645
                buttonImageURL = "";
 
646
        }
 
647
        
 
648
        this.settings.button_image_url = buttonImageURL;
 
649
        this.callFlash("SetButtonImageURL", [buttonImageURL]);
 
650
};
 
651
 
 
652
// Public: setButtonDimensions resizes the Flash Movie and button
 
653
SWFUpload.prototype.setButtonDimensions = function (width, height) {
 
654
        this.settings.button_width = width;
 
655
        this.settings.button_height = height;
 
656
        
 
657
        var movie = this.getMovieElement();
 
658
        if (movie != undefined) {
 
659
                movie.style.width = width + "px";
 
660
                movie.style.height = height + "px";
 
661
        }
 
662
        
 
663
        this.callFlash("SetButtonDimensions", [width, height]);
 
664
};
 
665
// Public: setButtonText Changes the text overlaid on the button
 
666
SWFUpload.prototype.setButtonText = function (html) {
 
667
        this.settings.button_text = html;
 
668
        this.callFlash("SetButtonText", [html]);
 
669
};
 
670
// Public: setButtonTextPadding changes the top and left padding of the text overlay
 
671
SWFUpload.prototype.setButtonTextPadding = function (left, top) {
 
672
        this.settings.button_text_top_padding = top;
 
673
        this.settings.button_text_left_padding = left;
 
674
        this.callFlash("SetButtonTextPadding", [left, top]);
 
675
};
 
676
 
 
677
// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
 
678
SWFUpload.prototype.setButtonTextStyle = function (css) {
 
679
        this.settings.button_text_style = css;
 
680
        this.callFlash("SetButtonTextStyle", [css]);
 
681
};
 
682
// Public: setButtonDisabled disables/enables the button
 
683
SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
 
684
        this.settings.button_disabled = isDisabled;
 
685
        this.callFlash("SetButtonDisabled", [isDisabled]);
 
686
};
 
687
// Public: setButtonAction sets the action that occurs when the button is clicked
 
688
SWFUpload.prototype.setButtonAction = function (buttonAction) {
 
689
        this.settings.button_action = buttonAction;
 
690
        this.callFlash("SetButtonAction", [buttonAction]);
 
691
};
 
692
 
 
693
// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button
 
694
SWFUpload.prototype.setButtonCursor = function (cursor) {
 
695
        this.settings.button_cursor = cursor;
 
696
        this.callFlash("SetButtonCursor", [cursor]);
 
697
};
 
698
 
 
699
/* *******************************
 
700
        Flash Event Interfaces
 
701
        These functions are used by Flash to trigger the various
 
702
        events.
 
703
        
 
704
        All these functions a Private.
 
705
        
 
706
        Because the ExternalInterface library is buggy the event calls
 
707
        are added to a queue and the queue then executed by a setTimeout.
 
708
        This ensures that events are executed in a determinate order and that
 
709
        the ExternalInterface bugs are avoided.
 
710
******************************* */
 
711
 
 
712
SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
 
713
        // Warning: Don't call this.debug inside here or you'll create an infinite loop
 
714
        
 
715
        if (argumentArray == undefined) {
 
716
                argumentArray = [];
 
717
        } else if (!(argumentArray instanceof Array)) {
 
718
                argumentArray = [argumentArray];
 
719
        }
 
720
        
 
721
        var self = this;
 
722
        if (typeof this.settings[handlerName] === "function") {
 
723
                // Queue the event
 
724
                this.eventQueue.push(function () {
 
725
                        this.settings[handlerName].apply(this, argumentArray);
 
726
                });
 
727
                
 
728
                // Execute the next queued event
 
729
                setTimeout(function () {
 
730
                        self.executeNextEvent();
 
731
                }, 0);
 
732
                
 
733
        } else if (this.settings[handlerName] !== null) {
 
734
                throw "Event handler " + handlerName + " is unknown or is not a function";
 
735
        }
 
736
};
 
737
 
 
738
// Private: Causes the next event in the queue to be executed.  Since events are queued using a setTimeout
 
739
// we must queue them in order to garentee that they are executed in order.
 
740
SWFUpload.prototype.executeNextEvent = function () {
 
741
        // Warning: Don't call this.debug inside here or you'll create an infinite loop
 
742
 
 
743
        var  f = this.eventQueue ? this.eventQueue.shift() : null;
 
744
        if (typeof(f) === "function") {
 
745
                f.apply(this);
 
746
        }
 
747
};
 
748
 
 
749
// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
 
750
// properties that contain characters that are not valid for JavaScript identifiers. To work around this
 
751
// the Flash Component escapes the parameter names and we must unescape again before passing them along.
 
752
SWFUpload.prototype.unescapeFilePostParams = function (file) {
 
753
        var reg = /[$]([0-9a-f]{4})/i;
 
754
        var unescapedPost = {};
 
755
        var uk;
 
756
 
 
757
        if (file != undefined) {
 
758
                for (var k in file.post) {
 
759
                        if (file.post.hasOwnProperty(k)) {
 
760
                                uk = k;
 
761
                                var match;
 
762
                                while ((match = reg.exec(uk)) !== null) {
 
763
                                        uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
 
764
                                }
 
765
                                unescapedPost[uk] = file.post[k];
 
766
                        }
 
767
                }
 
768
 
 
769
                file.post = unescapedPost;
 
770
        }
 
771
 
 
772
        return file;
 
773
};
 
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.
 
786
SWFUpload.prototype.flashReady = function () {
 
787
        // Check that the movie element is loaded correctly with its ExternalInterface methods defined
 
788
        var movieElement = this.getMovieElement();
 
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) {
 
803
        // Pro-actively unhook all the Flash functions
 
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) {
 
813
                                }
 
814
                        }
 
815
                }
 
816
        } catch (ex1) {
 
817
        
 
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
 
 
832
};
 
833
 
 
834
 
 
835
/* This is a chance to do something before the browse window opens */
 
836
SWFUpload.prototype.fileDialogStart = function () {
 
837
        this.queueEvent("file_dialog_start_handler");
 
838
};
 
839
 
 
840
 
 
841
/* Called when a file is successfully added to the queue. */
 
842
SWFUpload.prototype.fileQueued = function (file) {
 
843
        file = this.unescapeFilePostParams(file);
 
844
        this.queueEvent("file_queued_handler", file);
 
845
};
 
846
 
 
847
 
 
848
/* Handle errors that occur when an attempt to queue a file fails. */
 
849
SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
 
850
        file = this.unescapeFilePostParams(file);
 
851
        this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
 
852
};
 
853
 
 
854
/* Called after the file dialog has closed and the selected files have been queued.
 
855
        You could call startUpload here if you want the queued files to begin uploading immediately. */
 
856
SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
 
857
        this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
 
858
};
 
859
 
 
860
SWFUpload.prototype.uploadStart = function (file) {
 
861
        file = this.unescapeFilePostParams(file);
 
862
        this.queueEvent("return_upload_start_handler", file);
 
863
};
 
864
 
 
865
SWFUpload.prototype.returnUploadStart = function (file) {
 
866
        var returnValue;
 
867
        if (typeof this.settings.upload_start_handler === "function") {
 
868
                file = this.unescapeFilePostParams(file);
 
869
                returnValue = this.settings.upload_start_handler.call(this, file);
 
870
        } else if (this.settings.upload_start_handler != undefined) {
 
871
                throw "upload_start_handler must be a function";
 
872
        }
 
873
 
 
874
        // Convert undefined to true so if nothing is returned from the upload_start_handler it is
 
875
        // interpretted as 'true'.
 
876
        if (returnValue === undefined) {
 
877
                returnValue = true;
 
878
        }
 
879
        
 
880
        returnValue = !!returnValue;
 
881
        
 
882
        this.callFlash("ReturnUploadStart", [returnValue]);
 
883
};
 
884
 
 
885
 
 
886
 
 
887
SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
 
888
        file = this.unescapeFilePostParams(file);
 
889
        this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
 
890
};
 
891
 
 
892
SWFUpload.prototype.uploadError = function (file, errorCode, message) {
 
893
        file = this.unescapeFilePostParams(file);
 
894
        this.queueEvent("upload_error_handler", [file, errorCode, message]);
 
895
};
 
896
 
 
897
SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
 
898
        file = this.unescapeFilePostParams(file);
 
899
        this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
 
900
};
 
901
 
 
902
SWFUpload.prototype.uploadComplete = function (file) {
 
903
        file = this.unescapeFilePostParams(file);
 
904
        this.queueEvent("upload_complete_handler", file);
 
905
};
 
906
 
 
907
/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
 
908
   internal debug console.  You can override this event and have messages written where you want. */
 
909
SWFUpload.prototype.debug = function (message) {
 
910
        this.queueEvent("debug_handler", message);
 
911
};
 
912
 
 
913
 
 
914
/* **********************************
 
915
        Debug Console
 
916
        The debug console is a self contained, in page location
 
917
        for debug message to be sent.  The Debug Console adds
 
918
        itself to the body if necessary.
 
919
 
 
920
        The console is automatically scrolled as messages appear.
 
921
        
 
922
        If you are using your own debug handler or when you deploy to production and
 
923
        have debug disabled you can remove these functions to reduce the file size
 
924
        and complexity.
 
925
********************************** */
 
926
   
 
927
// Private: debugMessage is the default debug_handler.  If you want to print debug messages
 
928
// call the debug() function.  When overriding the function your own function should
 
929
// check to see if the debug setting is true before outputting debug information.
 
930
SWFUpload.prototype.debugMessage = function (message) {
 
931
        if (this.settings.debug) {
 
932
                var exceptionMessage, exceptionValues = [];
 
933
 
 
934
                // Check for an exception object and print it nicely
 
935
                if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") {
 
936
                        for (var key in message) {
 
937
                                if (message.hasOwnProperty(key)) {
 
938
                                        exceptionValues.push(key + ": " + message[key]);
 
939
                                }
 
940
                        }
 
941
                        exceptionMessage = exceptionValues.join("\n") || "";
 
942
                        exceptionValues = exceptionMessage.split("\n");
 
943
                        exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
 
944
                        SWFUpload.Console.writeLine(exceptionMessage);
 
945
                } else {
 
946
                        SWFUpload.Console.writeLine(message);
 
947
                }
 
948
        }
 
949
};
 
950
 
 
951
SWFUpload.Console = {};
 
952
SWFUpload.Console.writeLine = function (message) {
 
953
        var console, documentForm;
 
954
 
 
955
        try {
 
956
                console = document.getElementById("SWFUpload_Console");
 
957
 
 
958
                if (!console) {
 
959
                        documentForm = document.createElement("form");
 
960
                        document.getElementsByTagName("body")[0].appendChild(documentForm);
 
961
 
 
962
                        console = document.createElement("textarea");
 
963
                        console.id = "SWFUpload_Console";
 
964
                        console.style.fontFamily = "monospace";
 
965
                        console.setAttribute("wrap", "off");
 
966
                        console.wrap = "off";
 
967
                        console.style.overflow = "auto";
 
968
                        console.style.width = "700px";
 
969
                        console.style.height = "350px";
 
970
                        console.style.margin = "5px";
 
971
                        documentForm.appendChild(console);
 
972
                }
 
973
 
 
974
                console.value += message + "\n";
 
975
 
 
976
                console.scrollTop = console.scrollHeight - console.clientHeight;
 
977
        } catch (ex) {
 
978
                alert("Exception: " + ex.name + " Message: " + ex.message);
 
979
        }
 
980
};