X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/11be8dc178e77d0b46189bbd8e33a216a9b90942..e0feb3b2e5b436a06bbb04fbc838d1cd6ec95399:/wp-includes/js/swfupload/swfupload.js diff --git a/wp-includes/js/swfupload/swfupload.js b/wp-includes/js/swfupload/swfupload.js index 849cf28e..9c950d4e 100644 --- a/wp-includes/js/swfupload/swfupload.js +++ b/wp-includes/js/swfupload/swfupload.js @@ -3,7 +3,7 @@ * * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ * - * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License: + * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz�n and Mammon Media and is released under the MIT License: * http://www.opensource.org/licenses/mit-license.php * * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: @@ -31,6 +31,7 @@ SWFUpload.prototype.initSWFUpload = function (settings) { this.movieName = "SWFUpload_" + SWFUpload.movieCount++; this.movieElement = null; + // Setup global control tracking SWFUpload.instances[this.movieName] = this; @@ -49,7 +50,7 @@ SWFUpload.prototype.initSWFUpload = function (settings) { /* *************** */ SWFUpload.instances = {}; SWFUpload.movieCount = 0; -SWFUpload.version = "2.2.0 Beta 2"; +SWFUpload.version = "2.2.0 2009-03-25"; SWFUpload.QUEUE_ERROR = { QUEUE_LIMIT_EXCEEDED : -100, FILE_EXCEEDS_SIZE_LIMIT : -110, @@ -90,6 +91,27 @@ SWFUpload.WINDOW_MODE = { OPAQUE : "opaque" }; +// Private: takes a URL, determines if it is relative and converts to an absolute URL +// using the current site. Only processes the URL if it can, otherwise returns the URL untouched +SWFUpload.completeURL = function(url) { + if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) { + return url; + } + + var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : ""); + + var indexSlash = window.location.pathname.lastIndexOf("/"); + if (indexSlash <= 0) { + path = "/"; + } else { + path = window.location.pathname.substr(0, indexSlash) + "/"; + } + + return /*currentURL +*/ path + url; + +}; + + /* ******************** */ /* Instance Members */ /* ******************** */ @@ -103,11 +125,13 @@ SWFUpload.prototype.initSettings = function () { // Upload backend settings this.ensureDefault("upload_url", ""); + this.ensureDefault("preserve_relative_urls", false); this.ensureDefault("file_post_name", "Filedata"); this.ensureDefault("post_params", {}); this.ensureDefault("use_query_string", false); this.ensureDefault("requeue_on_error", false); this.ensureDefault("http_success", []); + this.ensureDefault("assume_success_timeout", 0); // File Settings this.ensureDefault("file_types", "*.*"); @@ -130,7 +154,8 @@ SWFUpload.prototype.initSettings = function () { this.ensureDefault("button_text_left_padding", 0); this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); this.ensureDefault("button_disabled", false); - this.ensureDefault("button_placeholder_id", null); + this.ensureDefault("button_placeholder_id", ""); + this.ensureDefault("button_placeholder", null); this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW); this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW); @@ -160,50 +185,21 @@ SWFUpload.prototype.initSettings = function () { this.customSettings = this.settings.custom_settings; // Update the flash url if needed - if (this.settings.prevent_swf_caching) { - this.settings.flash_url = this.settings.flash_url + "?swfuploadrnd=" + Math.floor(Math.random() * 999999999); + if (!!this.settings.prevent_swf_caching) { + this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime(); + } + + if (!this.settings.preserve_relative_urls) { + //this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url); // Don't need to do this one since flash doesn't look at it + this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url); + this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url); } delete this.ensureDefault; }; +// Private: loadFlash replaces the button_placeholder element with the flash movie. SWFUpload.prototype.loadFlash = function () { - if (this.settings.button_placeholder_id !== "") { - this.replaceWithFlash(); - } else { - this.appendFlash(); - } -}; - -// Private: appendFlash gets the HTML tag for the Flash -// It then appends the flash to the body -SWFUpload.prototype.appendFlash = function () { - var targetElement, container; - - // Make sure an element with the ID we are going to use doesn't already exist - if (document.getElementById(this.movieName) !== null) { - throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; - } - - // Get the body tag where we will be adding the flash movie - targetElement = document.getElementsByTagName("body")[0]; - - if (targetElement == undefined) { - throw "Could not find the 'body' element."; - } - - // Append the container and load the flash - container = document.createElement("div"); - container.style.width = "1px"; - container.style.height = "1px"; - container.style.overflow = "hidden"; - - targetElement.appendChild(container); - container.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) -}; - -// Private: replaceWithFlash replaces the button_placeholder element with the flash movie. -SWFUpload.prototype.replaceWithFlash = function () { var targetElement, tempParent; // Make sure an element with the ID we are going to use doesn't already exist @@ -212,10 +208,10 @@ SWFUpload.prototype.replaceWithFlash = function () { } // Get the element where we will be placing the flash movie - targetElement = document.getElementById(this.settings.button_placeholder_id); + targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder; if (targetElement == undefined) { - throw "Could not find the placeholder element."; + throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; } // Append the container and load the flash @@ -223,13 +219,18 @@ SWFUpload.prototype.replaceWithFlash = function () { tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + // Fix IE Flash/Form bug + if (window[this.movieName] == undefined) { + window[this.movieName] = this.getMovieElement(); + } + }; // Private: getFlashHTML generates the object tag needed to embed the flash in to the document SWFUpload.prototype.getFlashHTML = function () { // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay return ['', - '', + '', '', '', '', @@ -251,6 +252,7 @@ SWFUpload.prototype.getFlashVars = function () { "&useQueryString=", encodeURIComponent(this.settings.use_query_string), "&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), "&httpSuccess=", encodeURIComponent(httpSuccessString), + "&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout), "&params=", encodeURIComponent(paramString), "&filePostName=", encodeURIComponent(this.settings.file_post_name), "&fileTypes=", encodeURIComponent(this.settings.file_types), @@ -306,46 +308,54 @@ SWFUpload.prototype.buildParamString = function () { // Public: Used to remove a SWFUpload instance from the page. This method strives to remove // all references to the SWF, and other objects so memory is properly freed. // Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. +// Credits: Major improvements provided by steffen SWFUpload.prototype.destroy = function () { try { // Make sure Flash is done before we try to remove it - this.stopUpload(); + this.cancelUpload(null, false); + // Remove the SWFUpload DOM nodes var movieElement = null; - try { - movieElement = this.getMovieElement(); - } catch (ex) { - } + movieElement = this.getMovieElement(); - if (movieElement != undefined && movieElement.parentNode != undefined && typeof movieElement.parentNode.removeChild === "function") { - var container = movieElement.parentNode; - if (container != undefined) { - container.removeChild(movieElement); - if (container.parentNode != undefined && typeof container.parentNode.removeChild === "function") { - container.parentNode.removeChild(container); - } + if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + // Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround) + for (var i in movieElement) { + try { + if (typeof(movieElement[i]) === "function") { + movieElement[i] = null; + } + } catch (ex1) {} } + + // Remove the Movie Element from the page + try { + movieElement.parentNode.removeChild(movieElement); + } catch (ex) {} } - // Destroy references + // Remove IE form fix reference + window[this.movieName] = null; + + // Destroy other references SWFUpload.instances[this.movieName] = null; delete SWFUpload.instances[this.movieName]; - delete this.movieElement; - delete this.settings; - delete this.customSettings; - delete this.eventQueue; - delete this.movieName; + this.movieElement = null; + this.settings = null; + this.customSettings = null; + this.eventQueue = null; + this.movieName = null; - delete window[this.movieName]; return true; - } catch (ex1) { + } catch (ex2) { return false; } }; + // Public: displayDebugInfo prints out settings and configuration // information about this SWFUpload instance. // This function (and any references to it) can be deleted when placing @@ -362,6 +372,7 @@ SWFUpload.prototype.displayDebugInfo = function () { "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n", "\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n", "\t", "http_success: ", this.settings.http_success.join(", "), "\n", + "\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n", "\t", "file_post_name: ", this.settings.file_post_name, "\n", "\t", "post_params: ", this.settings.post_params.toString(), "\n", "\t", "file_types: ", this.settings.file_types, "\n", @@ -374,6 +385,7 @@ SWFUpload.prototype.displayDebugInfo = function () { "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n", "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n", + "\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n", "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n", "\t", "button_width: ", this.settings.button_width.toString(), "\n", "\t", "button_height: ", this.settings.button_height.toString(), "\n", @@ -430,33 +442,23 @@ SWFUpload.prototype.callFlash = function (functionName, argumentArray) { argumentArray = argumentArray || []; var movieElement = this.getMovieElement(); - var returnValue; + var returnValue, returnString; - if (typeof movieElement[functionName] === "function") { - // We have to go through all this if/else stuff because the Flash functions don't have apply() and only accept the exact number of arguments. - if (argumentArray.length === 0) { - returnValue = movieElement[functionName](); - } else if (argumentArray.length === 1) { - returnValue = movieElement[functionName](argumentArray[0]); - } else if (argumentArray.length === 2) { - returnValue = movieElement[functionName](argumentArray[0], argumentArray[1]); - } else if (argumentArray.length === 3) { - returnValue = movieElement[functionName](argumentArray[0], argumentArray[1], argumentArray[2]); - } else { - throw "Too many arguments"; - } - - // Unescape file post param values - if (returnValue != undefined && typeof returnValue.post === "object") { - returnValue = this.unescapeFilePostParams(returnValue); - } - - return returnValue; - } else { - throw "Invalid function name: " + functionName; + // Flash's method if calling ExternalInterface methods (code adapted from MooTools). + try { + returnString = movieElement.CallFunction('' + __flash__argumentsToXML(argumentArray, 0) + ''); + returnValue = eval(returnString); + } catch (ex) { + throw "Call to " + functionName + " failed"; + } + + // Unescape file post param values + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); } -}; + return returnValue; +}; /* ***************************** -- Flash control methods -- @@ -464,17 +466,19 @@ SWFUpload.prototype.callFlash = function (functionName, argumentArray) { to operate SWFUpload ***************************** */ +// WARNING: this function does not work in Flash Player 10 // Public: selectFile causes a File Selection Dialog window to appear. This -// dialog only allows 1 file to be selected. WARNING: this function does not work in Flash Player 10 +// dialog only allows 1 file to be selected. SWFUpload.prototype.selectFile = function () { this.callFlash("SelectFile"); }; +// WARNING: this function does not work in Flash Player 10 // Public: selectFiles causes a File Selection Dialog window to appear/ This // dialog allows the user to select any number of files // Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. // If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around -// for this bug. WARNING: this function does not work in Flash Player 10 +// for this bug. SWFUpload.prototype.selectFiles = function () { this.callFlash("SelectFiles"); }; @@ -623,6 +627,11 @@ SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) { this.callFlash("SetHTTPSuccess", [http_status_codes]); }; +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) { + this.settings.assume_success_timeout = timeout_seconds; + this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]); +}; // Public: setDebugEnabled changes the debug_enabled setting SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { @@ -763,21 +772,65 @@ SWFUpload.prototype.unescapeFilePostParams = function (file) { return file; }; +// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working) +SWFUpload.prototype.testExternalInterface = function () { + try { + return this.callFlash("TestExternalInterface"); + } catch (ex) { + return false; + } +}; + +// Private: This event is called by Flash when it has finished loading. Don't modify this. +// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded. SWFUpload.prototype.flashReady = function () { // Check that the movie element is loaded correctly with its ExternalInterface methods defined var movieElement = this.getMovieElement(); - if (typeof movieElement.StartUpload !== "function") { - throw "ExternalInterface methods failed to initialize."; - } - // Fix IE Flash/Form bug - if (window[this.movieName] == undefined) { - window[this.movieName] = movieElement; + if (!movieElement) { + this.debug("Flash called back ready but the flash movie can't be found."); + return; } + + this.cleanUp(movieElement); this.queueEvent("swfupload_loaded_handler"); }; +// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE. +// This function is called by Flash each time the ExternalInterface functions are created. +SWFUpload.prototype.cleanUp = function (movieElement) { + // Pro-actively unhook all the Flash functions + try { + if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); + for (var key in movieElement) { + try { + if (typeof(movieElement[key]) === "function") { + movieElement[key] = null; + } + } catch (ex) { + } + } + } + } catch (ex1) { + + } + + // Fix Flashes own cleanup code so if the SWFMovie was removed from the page + // it doesn't display errors. + window["__flash__removeCallback"] = function (instance, name) { + try { + if (instance) { + instance[name] = null; + } + } catch (flashEx) { + + } + }; + +}; + /* This is a chance to do something before the browse window opens */ SWFUpload.prototype.fileDialogStart = function () { @@ -800,8 +853,8 @@ SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { /* Called after the file dialog has closed and the selected files have been queued. You could call startUpload here if you want the queued files to begin uploading immediately. */ -SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued) { - this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued]); +SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) { + this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]); }; SWFUpload.prototype.uploadStart = function (file) { @@ -841,9 +894,9 @@ SWFUpload.prototype.uploadError = function (file, errorCode, message) { this.queueEvent("upload_error_handler", [file, errorCode, message]); }; -SWFUpload.prototype.uploadSuccess = function (file, serverData) { +SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) { file = this.unescapeFilePostParams(file); - this.queueEvent("upload_success_handler", [file, serverData]); + this.queueEvent("upload_success_handler", [file, serverData, responseReceived]); }; SWFUpload.prototype.uploadComplete = function (file) {