Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Autoría | Ultima modificación | Ver Log |

/**
 * jquery.plupload.queue.js
 *
 * Copyright 2009, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */

/* global jQuery:true, alert:true */

/**
jQuery based implementation of the Plupload API - multi-runtime file uploading API.

To use the widget you must include _jQuery_. It is not meant to be extended in any way and is provided to be
used as it is.

@example
        <!-- Instantiating: -->
        <div id="uploader">
                <p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
        </div>

        <script>
                $('#uploader').pluploadQueue({
                        url : '../upload.php',
                        filters : [
                                {title : "Image files", extensions : "jpg,gif,png"}
                        ],
                        rename: true,
                        flash_swf_url : '../../js/Moxie.swf',
                        silverlight_xap_url : '../../js/Moxie.xap',
                });
        </script>

@example
        // Retrieving a reference to plupload.Uploader object
        var uploader = $('#uploader').pluploadQueue();

        uploader.bind('FilesAdded', function() {

                // Autostart
                setTimeout(uploader.start, 1); // "detach" from the main thread
        });

@class pluploadQueue
@constructor
@param {Object} settings For detailed information about each option check documentation.
        @param {String} settings.url URL of the server-side upload handler.
        @param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
        @param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
        @param {Array} [settings.filters=[]] Set of file type filters, each one defined by hash of title and extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
        @param {String} [settings.flash_swf_url] URL of the Flash swf.
        @param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
        @param {Number|String} [settings.max_file_size] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
        @param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
        @param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
        @param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
        @param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
        @param {Boolean} [settings.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
        @param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
        @param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
                @param {Number} [settings.resize.width] If image is bigger, it will be resized.
                @param {Number} [settings.resize.height] If image is bigger, it will be resized.
                @param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
                @param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
        @param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
        @param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
        @param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.

        @param {Boolean} [settings.dragdrop=true] Enable ability to add file to the queue by drag'n'dropping them from the desktop.
        @param {Boolean} [settings.rename=false] Enable ability to rename files in the queue.
        @param {Boolean} [settings.multiple_queues=true] Re-activate the widget after each upload procedure.
*/
;(function($, plupload) {
        var uploaders = {};

        function _(str) {
                return plupload.translate(str) || str;
        }

        function renderUI(id, target) {
                // Remove all existing non plupload items
                target.contents().each(function(i, node) {
                        node = $(node);

                        if (!node.is('.plupload')) {
                                node.remove();
                        }
                });

                target.prepend(
                        '<div class="plupload_wrapper plupload_scroll">' +
                                '<div id="' + id + '_container" class="plupload_container">' +
                                        '<div class="plupload">' +
                                                '<div class="plupload_header">' +
                                                        '<div class="plupload_header_content">' +
                                                                '<div class="plupload_header_title">' + _('Select files') + '</div>' +
                                                                '<div class="plupload_header_text">' + _('Add files to the upload queue and click the start button.') + '</div>' +
                                                        '</div>' +
                                                '</div>' +

                                                '<div class="plupload_content">' +
                                                        '<div class="plupload_filelist_header">' +
                                                                '<div class="plupload_file_name">' + _('Filename') + '</div>' +
                                                                '<div class="plupload_file_action">&nbsp;</div>' +
                                                                '<div class="plupload_file_status"><span>' + _('Status') + '</span></div>' +
                                                                '<div class="plupload_file_size">' + _('Size') + '</div>' +
                                                                '<div class="plupload_clearer">&nbsp;</div>' +
                                                        '</div>' +

                                                        '<ul id="' + id + '_filelist" class="plupload_filelist"></ul>' +

                                                        '<div class="plupload_filelist_footer">' +
                                                                '<div class="plupload_file_name">' +
                                                                        '<div class="plupload_buttons">' +
                                                                                '<a href="#" class="plupload_button plupload_add" id="' + id + '_browse">' + _('Add Files') + '</a>' +
                                                                                '<a href="#" class="plupload_button plupload_start">' + _('Start Upload') + '</a>' +
                                                                        '</div>' +
                                                                        '<span class="plupload_upload_status"></span>' +
                                                                '</div>' +
                                                                '<div class="plupload_file_action"></div>' +
                                                                '<div class="plupload_file_status"><span class="plupload_total_status">0%</span></div>' +
                                                                '<div class="plupload_file_size"><span class="plupload_total_file_size">0 b</span></div>' +
                                                                '<div class="plupload_progress">' +
                                                                        '<div class="plupload_progress_container">' +
                                                                                '<div class="plupload_progress_bar"></div>' +
                                                                        '</div>' +
                                                                '</div>' +
                                                                '<div class="plupload_clearer">&nbsp;</div>' +
                                                        '</div>' +
                                                '</div>' +
                                        '</div>' +
                                '</div>' +
                                '<input type="hidden" id="' + id + '_count" name="' + id + '_count" value="0" />' +
                        '</div>'
                );
        }

        $.fn.pluploadQueue = function(settings) {
                if (settings) {
                        this.each(function() {
                                var uploader, target, id, contents_bak;

                                target = $(this);
                                id = target.attr('id');

                                if (!id) {
                                        id = plupload.guid();
                                        target.attr('id', id);
                                }

                                contents_bak = target.html();
                                renderUI(id, target);

                                settings = $.extend({
                                        dragdrop : true,
                                        browse_button : id + '_browse',
                                        container : id
                                }, settings);

                                // Enable drag/drop (see PostInit handler as well)
                                if (settings.dragdrop) {
                                        settings.drop_element = id + '_filelist';
                                }

                                uploader = new plupload.Uploader(settings);

                                uploaders[id] = uploader;

                                function handleStatus(file) {
                                        var actionClass;

                                        if (file.status == plupload.DONE) {
                                                actionClass = 'plupload_done';
                                        }

                                        if (file.status == plupload.FAILED) {
                                                actionClass = 'plupload_failed';
                                        }

                                        if (file.status == plupload.QUEUED) {
                                                actionClass = 'plupload_delete';
                                        }

                                        if (file.status == plupload.UPLOADING) {
                                                actionClass = 'plupload_uploading';
                                        }

                                        var icon = $('#' + file.id).attr('class', actionClass).find('a').css('display', 'block');
                                        if (file.hint) {
                                                icon.attr('title', file.hint);
                                        }
                                }

                                function updateTotalProgress() {
                                        $('span.plupload_total_status', target).html(uploader.total.percent + '%');
                                        $('div.plupload_progress_bar', target).css('width', uploader.total.percent + '%');
                                        $('span.plupload_upload_status', target).html(
                                                plupload.sprintf(_('Uploaded %d/%d files'), uploader.total.uploaded, uploader.files.length)
                                        );
                                }

                                function updateList() {
                                        var fileList = $('ul.plupload_filelist', target).html(''), inputCount = 0, inputHTML;

                                        $.each(uploader.files, function(i, file) {
                                                inputHTML = '';

                                                if (file.status == plupload.DONE) {
                                                        if (file.target_name) {
                                                                inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_tmpname" value="' + plupload.xmlEncode(file.target_name) + '" />';
                                                        }

                                                        inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_name" value="' + plupload.xmlEncode(file.name) + '" />';
                                                        inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_status" value="' + (file.status == plupload.DONE ? 'done' : 'failed') + '" />';

                                                        inputCount++;

                                                        $('#' + id + '_count').val(inputCount);
                                                }

                                                fileList.append(
                                                        '<li id="' + file.id + '">' +
                                                                '<div class="plupload_file_name"><span>' + file.name + '</span></div>' +
                                                                '<div class="plupload_file_action"><a href="#"></a></div>' +
                                                                '<div class="plupload_file_status">' + file.percent + '%</div>' +
                                                                '<div class="plupload_file_size">' + plupload.formatSize(file.size) + '</div>' +
                                                                '<div class="plupload_clearer">&nbsp;</div>' +
                                                                inputHTML +
                                                        '</li>'
                                                );

                                                handleStatus(file);

                                                $('#' + file.id + '.plupload_delete a').click(function(e) {
                                                        $('#' + file.id).remove();
                                                        uploader.removeFile(file);

                                                        e.preventDefault();
                                                });
                                        });

                                        $('span.plupload_total_file_size', target).html(plupload.formatSize(uploader.total.size));

                                        if (uploader.total.queued === 0) {
                                                $('span.plupload_add_text', target).html(_('Add Files'));
                                        } else {
                                                $('span.plupload_add_text', target).html(plupload.sprintf(_('%d files queued'), uploader.total.queued));
                                        }

                                        $('a.plupload_start', target).toggleClass('plupload_disabled', uploader.files.length == (uploader.total.uploaded + uploader.total.failed));

                                        // Scroll to end of file list
                                        fileList[0].scrollTop = fileList[0].scrollHeight;

                                        updateTotalProgress();

                                        // Re-add drag message if there is no files
                                        if (!uploader.files.length && uploader.features.dragdrop && uploader.settings.dragdrop) {
                                                $('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
                                        }
                                }

                                function destroy() {
                                        delete uploaders[id];
                                        uploader.destroy();
                                        target.html(contents_bak);
                                        uploader = target = contents_bak = null;
                                }

                                uploader.bind("UploadFile", function(up, file) {
                                        $('#' + file.id).addClass('plupload_current_file');
                                });

                                uploader.bind('Init', function(up, res) {
                                        // Enable rename support
                                        if (!settings.unique_names && settings.rename) {
                                                target.on('click', '#' + id + '_filelist div.plupload_file_name span', function(e) {
                                                        var targetSpan = $(e.target), file, parts, name, ext = "";

                                                        // Get file name and split out name and extension
                                                        file = up.getFile(targetSpan.parents('li')[0].id);
                                                        name = file.name;
                                                        parts = /^(.+)(\.[^.]+)$/.exec(name);
                                                        if (parts) {
                                                                name = parts[1];
                                                                ext = parts[2];
                                                        }

                                                        // Display input element
                                                        targetSpan.hide().after('<input type="text" />');
                                                        targetSpan.next().val(name).focus().blur(function() {
                                                                targetSpan.show().next().remove();
                                                        }).keydown(function(e) {
                                                                var targetInput = $(this);

                                                                if (e.keyCode == 13) {
                                                                        e.preventDefault();

                                                                        // Rename file and glue extension back on
                                                                        file.name = targetInput.val() + ext;
                                                                        targetSpan.html(file.name);
                                                                        targetInput.blur();
                                                                }
                                                        });
                                                });
                                        }

                                        $('#' + id + '_container').attr('title', 'Using runtime: ' + res.runtime);

                                        $('a.plupload_start', target).click(function(e) {
                                                if (!$(this).hasClass('plupload_disabled')) {
                                                        uploader.start();
                                                }

                                                e.preventDefault();
                                        });

                                        $('a.plupload_stop', target).click(function(e) {
                                                e.preventDefault();
                                                uploader.stop();
                                        });

                                        $('a.plupload_start', target).addClass('plupload_disabled');
                                });

                                uploader.bind("Error", function(up, err) {
                                        var file = err.file, message;

                                        if (file) {
                                                message = err.message;

                                                if (err.details) {
                                                        message += " (" + err.details + ")";
                                                }

                                                if (err.code == plupload.FILE_SIZE_ERROR) {
                                                        alert(_("Error: File too large:") + " " + file.name);
                                                }

                                                if (err.code == plupload.FILE_EXTENSION_ERROR) {
                                                        alert(_("Error: Invalid file extension:") + " " + file.name);
                                                }

                                                file.hint = message;
                                                $('#' + file.id).attr('class', 'plupload_failed').find('a').css('display', 'block').attr('title', message);
                                        }

                                        if (err.code === plupload.INIT_ERROR) {
                                                setTimeout(function() {
                                                        destroy();
                                                }, 1);
                                        }
                                });

                                uploader.bind("PostInit", function(up) {
                                        // features are populated only after input components are fully instantiated
                                        if (up.settings.dragdrop && up.features.dragdrop) {
                                                $('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
                                        }
                                });

                                uploader.init();

                                uploader.bind('StateChanged', function() {
                                        if (uploader.state === plupload.STARTED) {
                                                $('li.plupload_delete a,div.plupload_buttons', target).hide();
                                                uploader.disableBrowse(true);

                                                $('span.plupload_upload_status,div.plupload_progress,a.plupload_stop', target).css('display', 'block');
                                                $('span.plupload_upload_status', target).html('Uploaded ' + uploader.total.uploaded + '/' + uploader.files.length + ' files');

                                                if (settings.multiple_queues) {
                                                        $('span.plupload_total_status,span.plupload_total_file_size', target).show();
                                                }
                                        } else {
                                                updateList();
                                                $('a.plupload_stop,div.plupload_progress', target).hide();
                                                $('a.plupload_delete', target).css('display', 'block');

                                                if (settings.multiple_queues && uploader.total.uploaded + uploader.total.failed == uploader.files.length) {
                                                        $(".plupload_buttons,.plupload_upload_status", target).css("display", "inline");
                                                        uploader.disableBrowse(false);

                                                        $(".plupload_start", target).addClass("plupload_disabled");
                                                        $('span.plupload_total_status,span.plupload_total_file_size', target).hide();
                                                }
                                        }
                                });

                                uploader.bind('FilesAdded', updateList);

                                uploader.bind('FilesRemoved', function() {
                                        // since the whole file list is redrawn for every change in the queue
                                        // we need to scroll back to the file removal point to avoid annoying
                                        // scrolling to the bottom bug (see #926)
                                        var scrollTop = $('#' + id + '_filelist').scrollTop();
                                        updateList();
                                        $('#' + id + '_filelist').scrollTop(scrollTop);
                                });

                                uploader.bind('FileUploaded', function(up, file) {
                                        handleStatus(file);
                                });

                                uploader.bind("UploadProgress", function(up, file) {
                                        // Set file specific progress
                                        $('#' + file.id + ' div.plupload_file_status', target).html(file.percent + '%');

                                        handleStatus(file);
                                        updateTotalProgress();
                                });

                                // Call setup function
                                if (settings.setup) {
                                        settings.setup(uploader);
                                }
                        });

                        return this;
                } else {
                        // Get uploader instance for specified element
                        return uploaders[$(this[0]).attr('id')];
                }
        };
})(jQuery, plupload);