Make WordPress Core


Ignore:
Timestamp:
05/17/2009 12:29:58 PM (15 years ago)
Author:
azaozz
Message:

Update SWFUpload to 2.2.0.1, see #9413

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/js/swfupload/swfupload.js

    r9421 r11372  
    3232        this.movieElement = null;
    3333
     34
    3435        // Setup global control tracking
    3536        SWFUpload.instances[this.movieName] = this;
     
    5051SWFUpload.instances = {};
    5152SWFUpload.movieCount = 0;
    52 SWFUpload.version = "2.2.0 Beta 2";
     53SWFUpload.version = "2.2.0 2009-03-25";
    5354SWFUpload.QUEUE_ERROR = {
    5455    QUEUE_LIMIT_EXCEEDED            : -100,
     
    9192};
    9293
     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
     96SWFUpload.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
    93115/* ******************** */
    94116/* Instance Members  */
     
    104126    // Upload backend settings
    105127    this.ensureDefault("upload_url", "");
     128    this.ensureDefault("preserve_relative_urls", false);
    106129    this.ensureDefault("file_post_name", "Filedata");
    107130    this.ensureDefault("post_params", {});
     
    109132    this.ensureDefault("requeue_on_error", false);
    110133    this.ensureDefault("http_success", []);
     134    this.ensureDefault("assume_success_timeout", 0);
    111135   
    112136    // File Settings
     
    131155    this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
    132156    this.ensureDefault("button_disabled", false);
    133     this.ensureDefault("button_placeholder_id", null);
     157    this.ensureDefault("button_placeholder_id", "");
     158    this.ensureDefault("button_placeholder", null);
    134159    this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
    135160    this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
     
    161186   
    162187    // Update the flash url if needed
    163     if (this.settings.prevent_swf_caching) {
    164         this.settings.flash_url = this.settings.flash_url + "?swfuploadrnd=" + Math.floor(Math.random() * 999999999);
     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);
    165196    }
    166197   
     
    168199};
    169200
     201// Private: loadFlash replaces the button_placeholder element with the flash movie.
    170202SWFUpload.prototype.loadFlash = function () {
    171     if (this.settings.button_placeholder_id !== "") {
    172         this.replaceWithFlash();
    173     } else {
    174         this.appendFlash();
    175     }
    176 };
    177 
    178 // Private: appendFlash gets the HTML tag for the Flash
    179 // It then appends the flash to the body
    180 SWFUpload.prototype.appendFlash = function () {
    181     var targetElement, container;
     203    var targetElement, tempParent;
    182204
    183205    // Make sure an element with the ID we are going to use doesn't already exist
     
    186208    }
    187209
    188     // Get the body tag where we will be adding the flash movie
    189     targetElement = document.getElementsByTagName("body")[0];
     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;
    190212
    191213    if (targetElement == undefined) {
    192         throw "Could not find the 'body' element.";
    193     }
    194 
    195     // Append the container and load the flash
    196     container = document.createElement("div");
    197     container.style.width = "1px";
    198     container.style.height = "1px";
    199     container.style.overflow = "hidden";
    200 
    201     targetElement.appendChild(container);
    202     container.innerHTML = this.getFlashHTML();  // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
    203 };
    204 
    205 // Private: replaceWithFlash replaces the button_placeholder element with the flash movie.
    206 SWFUpload.prototype.replaceWithFlash = function () {
    207     var targetElement, tempParent;
    208 
    209     // Make sure an element with the ID we are going to use doesn't already exist
    210     if (document.getElementById(this.movieName) !== null) {
    211         throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
    212     }
    213 
    214     // Get the element where we will be placing the flash movie
    215     targetElement = document.getElementById(this.settings.button_placeholder_id);
    216 
    217     if (targetElement == undefined) {
    218         throw "Could not find the placeholder element.";
     214        throw "Could not find the placeholder element: " + this.settings.button_placeholder_id;
    219215    }
    220216
     
    224220    targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
    225221
     222    // Fix IE Flash/Form bug
     223    if (window[this.movieName] == undefined) {
     224        window[this.movieName] = this.getMovieElement();
     225    }
     226   
    226227};
    227228
     
    230231    // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
    231232    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">',
    232                 '<param name="wmode" value="', this.settings.button_window_mode , '" />',
     233                '<param name="wmode" value="', this.settings.button_window_mode, '" />',
    233234                '<param name="movie" value="', this.settings.flash_url, '" />',
    234235                '<param name="quality" value="high" />',
     
    252253            "&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
    253254            "&amp;httpSuccess=", encodeURIComponent(httpSuccessString),
     255            "&amp;assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
    254256            "&amp;params=", encodeURIComponent(paramString),
    255257            "&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
     
    307309// all references to the SWF, and other objects so memory is properly freed.
    308310// 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
    309312SWFUpload.prototype.destroy = function () {
    310313    try {
    311314        // Make sure Flash is done before we try to remove it
    312         this.stopUpload();
     315        this.cancelUpload(null, false);
    313316       
     317
    314318        // Remove the SWFUpload DOM nodes
    315319        var movieElement = null;
    316         try {
    317             movieElement = this.getMovieElement();
    318         } catch (ex) {
     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) {}
    319336        }
    320337       
    321         if (movieElement != undefined && movieElement.parentNode != undefined && typeof movieElement.parentNode.removeChild === "function") {
    322             var container = movieElement.parentNode;
    323             if (container != undefined) {
    324                 container.removeChild(movieElement);
    325                 if (container.parentNode != undefined && typeof container.parentNode.removeChild === "function") {
    326                     container.parentNode.removeChild(container);
    327                 }
    328             }
    329         }
    330        
    331         // Destroy references
     338        // Remove IE form fix reference
     339        window[this.movieName] = null;
     340
     341        // Destroy other references
    332342        SWFUpload.instances[this.movieName] = null;
    333343        delete SWFUpload.instances[this.movieName];
    334344
    335         delete this.movieElement;
    336         delete this.settings;
    337         delete this.customSettings;
    338         delete this.eventQueue;
    339         delete this.movieName;
     345        this.movieElement = null;
     346        this.settings = null;
     347        this.customSettings = null;
     348        this.eventQueue = null;
     349        this.movieName = null;
    340350       
    341         delete window[this.movieName];
    342351       
    343352        return true;
    344     } catch (ex1) {
     353    } catch (ex2) {
    345354        return false;
    346355    }
    347356};
     357
    348358
    349359// Public: displayDebugInfo prints out settings and configuration
     
    363373            "\t", "requeue_on_error:         ", this.settings.requeue_on_error.toString(), "\n",
    364374            "\t", "http_success:             ", this.settings.http_success.join(", "), "\n",
     375            "\t", "assume_success_timeout:   ", this.settings.assume_success_timeout, "\n",
    365376            "\t", "file_post_name:           ", this.settings.file_post_name, "\n",
    366377            "\t", "post_params:              ", this.settings.post_params.toString(), "\n",
     
    375386
    376387            "\t", "button_placeholder_id:    ", this.settings.button_placeholder_id.toString(), "\n",
     388            "\t", "button_placeholder:       ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
    377389            "\t", "button_image_url:         ", this.settings.button_image_url.toString(), "\n",
    378390            "\t", "button_width:             ", this.settings.button_width.toString(), "\n",
     
    431443   
    432444    var movieElement = this.getMovieElement();
    433     var returnValue;
    434 
    435     if (typeof movieElement[functionName] === "function") {
    436         // 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.
    437         if (argumentArray.length === 0) {
    438             returnValue = movieElement[functionName]();
    439         } else if (argumentArray.length === 1) {
    440             returnValue = movieElement[functionName](argumentArray[0]);
    441         } else if (argumentArray.length === 2) {
    442             returnValue = movieElement[functionName](argumentArray[0], argumentArray[1]);
    443         } else if (argumentArray.length === 3) {
    444             returnValue = movieElement[functionName](argumentArray[0], argumentArray[1], argumentArray[2]);
    445         } else {
    446             throw "Too many arguments";
    447         }
    448        
    449         // Unescape file post param values
    450         if (returnValue != undefined && typeof returnValue.post === "object") {
    451             returnValue = this.unescapeFilePostParams(returnValue);
    452         }
    453        
    454         return returnValue;
    455     } else {
    456         throw "Invalid function name: " + functionName;
    457     }
    458 };
    459 
     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};
    460462
    461463/* *****************************
     
    465467   ***************************** */
    466468
     469// WARNING: this function does not work in Flash Player 10
    467470// Public: selectFile causes a File Selection Dialog window to appear.  This
    468 // dialog only allows 1 file to be selected. WARNING: this function does not work in Flash Player 10
     471// dialog only allows 1 file to be selected.
    469472SWFUpload.prototype.selectFile = function () {
    470473    this.callFlash("SelectFile");
    471474};
    472475
     476// WARNING: this function does not work in Flash Player 10
    473477// Public: selectFiles causes a File Selection Dialog window to appear/ This
    474478// dialog allows the user to select any number of files
    475479// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
    476480// If the selection name length is too long the dialog will fail in an unpredictable manner.  There is no work-around
    477 // for this bug.  WARNING: this function does not work in Flash Player 10
     481// for this bug.
    478482SWFUpload.prototype.selectFiles = function () {
    479483    this.callFlash("SelectFiles");
     
    624628};
    625629
     630// Public: setHTTPSuccess changes the http_success setting
     631SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
     632    this.settings.assume_success_timeout = timeout_seconds;
     633    this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
     634};
    626635
    627636// Public: setDebugEnabled changes the debug_enabled setting
     
    764773};
    765774
     775// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working)
     776SWFUpload.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.
    766786SWFUpload.prototype.flashReady = function () {
    767787    // Check that the movie element is loaded correctly with its ExternalInterface methods defined
    768788    var movieElement = this.getMovieElement();
    769     if (typeof movieElement.StartUpload !== "function") {
    770         throw "ExternalInterface methods failed to initialize.";
    771     }
    772 
    773     // Fix IE Flash/Form bug
    774     if (window[this.movieName] == undefined) {
    775         window[this.movieName] = movieElement;
    776     }
     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);
    777796   
    778797    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.
     802SWFUpload.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
    779832};
    780833
     
    801854/* Called after the file dialog has closed and the selected files have been queued.
    802855    You could call startUpload here if you want the queued files to begin uploading immediately. */
    803 SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued) {
    804     this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued]);
     856SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
     857    this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
    805858};
    806859
     
    842895};
    843896
    844 SWFUpload.prototype.uploadSuccess = function (file, serverData) {
     897SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
    845898    file = this.unescapeFilePostParams(file);
    846     this.queueEvent("upload_success_handler", [file, serverData]);
     899    this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
    847900};
    848901
Note: See TracChangeset for help on using the changeset viewer.