Changeset 6107


Ignore:
Timestamp:
05/04/12 18:00:28 (12 years ago)
Author:
gustavo
Message:

Ticket #2676 - Falha ao anexar arquivo no expresso mail

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/expressoMail1_2/js/draw_api.js

    r6106 r6107  
    17011701                                headers_msgs.followupflagged.id = DataLayer.put('followupflagged', headers_msgs.followupflagged); 
    17021702                                DataLayer.commit(false, false, function(data){ 
    1703                                 var fail = false; 
     1703                                        var fail = false; 
    17041704                                        $.each(data, function(index, value) { 
    1705                                                 fail = false; 
    1706                                                 if(typeof value != 'object' || !(value['id'])){ 
     1705                                                if(typeof value != 'object'){ 
    17071706                                                        fail = true; 
     1707                                                        alert(value); 
    17081708                                                } 
    17091709                                        }); 
     
    17201720                                                $('#td_message_followup_' + messageClickedId + ', ' +  
    17211721                                                'tr[role="'+messageClickedId+'_'+msg_folder+'"] #td_message_followup_search_' + messageClickedId).find(".flag-edited").css("background", "#CCCCCC"); 
    1722                                                 alert("Não foi possível sinalizar esta mensagem. \nDetalhes do erro: mensagem não contém o atributo message-id."); 
    17231722                                        } 
    17241723                                }); 
     
    30173016                //TODO Mudar quando API abstrair atualizações no cache 
    30183017                DataLayer.remove('labeled', false); 
    3019                 //DataLayer.get('labeled'); 
     3018                DataLayer.get('labeled'); 
    30203019                var labels = DataLayer.get("labeled", {filter: [ 
    30213020                                'AND', 
     
    30443043                                var id_labeled = $(event.target).attr("id"); 
    30453044                                //TODO Mudar quando API abstrair atualizações no cache 
    3046                                 //DataLayer.remove('labeled', false); 
    3047                                 //DataLayer.get('labeled'); 
     3045                                DataLayer.remove('labeled', false); 
     3046                                DataLayer.get('labeled'); 
    30483047                                DataLayer.remove('labeled', id_labeled); 
    30493048                                DataLayer.commit(false, false, function(){ 
     
    36783677        var fileUploadMSG = $('#fileupload_msg'+ID); 
    36793678        var maxAttachmentSize = (preferences.max_attachment_size !== "" && preferences.max_attachment_size != 0) ? (parseInt(preferences.max_attachment_size.replace('M', '')) * 1048576 ) : false; 
    3680  
    3681         fileUploadMSG.find(".button-files-upload").fileupload({ 
     3679         
     3680        fileUploadMSG.find(".button").button().filter(".fileinput-button").find("input:file").fileupload({ 
     3681                //singleFileUploads : true, 
     3682                sequentialUploads: true,  
    36823683                type: 'post', 
    36833684                dataType : 'json', 
    36843685                url: "../prototype/post.php", 
    3685                 forceIframeTransport: true, 
     3686                forceIframeTransport: false, 
     3687                dropZone : fileUploadMSG, 
    36863688                formData: function(form) { 
     3689                        $.each(this.files, function(index, value){ 
     3690                                 
     3691                        });  
    36873692                        return [ 
    36883693                                { 
     
    36993704                                } 
    37003705                        ]; 
    3701                 }, 
     3706                },       
    37023707                add: function (e, data) { 
    3703                          
    37043708                        if(!maxAttachmentSize || data.files[0].size < maxAttachmentSize || is_ie) { 
    37053709                                setTimeout(function() { 
    37063710                    $('#attDisposition'+ID).val('attachment'); 
    37073711                                        if(!data.fileInput){ 
    3708                                                 $(fileUploadMSG).find("input")[0].files = data.files; 
    3709                                                 data['fileInput'] = $(fileUploadMSG).find("input"); 
     3712                                                data.fileInput = fileUploadMSG.find("input:file"); 
     3713                                                 
     3714                                                //fileUploadMSG.find("input:file").trigger("change.undefined"); 
    37103715                                        } 
    3711                                         if(!data.form) 
    3712                                                 data['form'] = fileUploadMSG.parents("form:first"); 
    37133716                                        data.submit(); 
    37143717                                }, 3000); 
    3715                         }                
    3716                         var attach = {}; 
    3717                         attach.fullFileName = data.files[0].name; 
    3718                         attach.fileName = data.files[0].name; 
    3719                         if(data.files[0].name.length > 50) 
    3720                                 attach.fileName = data.files[0].name.substr(0, 32) + " ... " + data.files[0].name.substr(data.files[0].name.length-9, data.files[0].name.length); 
    3721                         attach.fileSize = formatBytes(data.files[0].size); 
    3722                         data.files[0].size = 300; 
    3723                         if(maxAttachmentSize && data.files[0].size > maxAttachmentSize) 
    3724                                 attach.error = 'Tamanho de arquivo nao permitido!!!' 
    3725  
    3726                         var upload = $(DataLayer.render("../prototype/modules/mail/templates/attachment_add_itemlist.ejs", {file : attach}));                            
    3727                         upload.find('.button.close').button({ 
    3728                                 icons: { 
    3729                                         primary: "ui-icon-close" 
    3730                                 }, 
    3731                                 text: false 
    3732                         }).click(function(){ 
    3733                                 var idAttach = $(this).parent().find('input[name="fileId[]"]').val(); 
    3734                                 fileUploadMSG.find(' .attachments-list').find('input[value="'+idAttach+'"]').remove(); 
    3735                                 delAttachment(ID, idAttach) 
    3736                                 $(this).parent().remove(); 
     3718                        } 
     3719                        $.each(data.files, function (index, file) { 
     3720                                var attach = {}; 
     3721                                attach.fullFileName = file.name; 
     3722                                attach.fileName = file.name; 
     3723                                if(file.name.length > 50) 
     3724                                        attach.fileName = file.name.substr(0, 32) + " ... " + file.name.substr(file.name.length-9, file.name.length); 
     3725                                attach.fileSize = formatBytes(file.size); 
     3726                                if(maxAttachmentSize && file.size > maxAttachmentSize) 
     3727                                        attach.error = 'Tamanho de arquivo nao permitido!!' 
     3728                                 
     3729                                var upload = $(DataLayer.render("../prototype/modules/mail/templates/attachment_add_itemlist.ejs", {file : attach}));                            
     3730                                upload.find('.button.close').button({ 
     3731                                        icons: { 
     3732                                                primary: "ui-icon-close" 
     3733                                        }, 
     3734                                        text: false 
     3735                                }).click(function(){ 
     3736                                        var idAttach = $(this).parent().find('input[name="fileId[]"]').val(); 
     3737                                        fileUploadMSG.find(' .attachments-list').find('input[value="'+idAttach+'"]').remove(); 
     3738                                        delAttachment(ID, idAttach) 
     3739                                        $(this).parent().remove(); 
     3740                                }); 
     3741                                 
     3742                                fileUploadMSG.find('.attachments-list').append(upload); 
     3743 
     3744                                if(!maxAttachmentSize || file.size < maxAttachmentSize){ 
     3745                                        if(data.fileInput){ 
     3746                                                fileUploadMSG.find('.fileinput-button.new').append(data.fileInput[0]).removeClass('new'); 
     3747                                                fileUploadMSG.find('.attachments-list').find('[type=file]').addClass('hidden');  
     3748                                        } 
     3749                                }else 
     3750                                        fileUploadMSG.find(' .fileinput-button.new').removeClass('new'); 
    37373751                        }); 
    3738  
    3739                         fileUploadMSG.find('.attachments-list').append(upload); 
    3740  
    3741                         if(!maxAttachmentSize || data.files[0].size < maxAttachmentSize) 
    3742                             fileUploadMSG.find('.attachments-list').find('[type=file]').addClass('hidden');      
    3743                         else 
    3744                             fileUploadMSG.find(' .fileinput-button.new').removeClass('new'); 
    37453752                }, 
    37463753                done: function(e, data){ 
     
    37643771            fileUploadMSG.find(' .in-progress:first').remove(); 
    37653772                } 
    3766         }).find('[name="files[]"]').css({"height" : "20px", "width": "100px", "border-width": "0 0 0px 0px", "-moz-transform" : "none","-o-transform" : 'none'}); 
    3767  
     3773        }).css({"height" : "20px", "width": "100px", "border-width": "0 0 0px 0px", "-moz-transform" : "none","-o-transform" : 'none'}) 
     3774        .end().end().filter(".message-attach-link").click(function(){ 
     3775                jQuery('#message-attach-dialog').html(DataLayer.render("../prototype/modules/attach_message/attach_message.ejs", {})); 
     3776                $( "#mailpreview_container span.ui-icon-close" ).click(); 
     3777                jQuery('#message-attach-dialog').dialog({ 
     3778                        width:920, 
     3779                        height:550, 
     3780                        resizable:false, 
     3781                        modal: true, 
     3782                        closeOnEscape:true, 
     3783                        close:function(event, ui) {event.stopPropagation(); }, 
     3784                        autoOpen:false 
     3785                }); 
     3786                 
     3787                 
     3788                jQuery.getScript("../prototype/modules/attach_message/attach_message.js", function(){ 
     3789                        jQuery('#message-attach-dialog').dialog('open'); 
     3790                        jQuery('#message-attach-attach-btn').unbind('click'); 
     3791                        jQuery('#message-attach-attach-btn').click(function(event){ 
     3792                                jQuery.each(selectedMessages, function(folder_name, messages) { 
     3793                                        jQuery.each(selectedMessages[folder_name], function(message_number, message) {  
     3794                                                if (message) { 
     3795                                                        var att = new Object(); 
     3796                                                        att.folder = folder_name; 
     3797                                                        att.uid = message_number; 
     3798                                                        att.type = 'imapMSG'; 
     3799                                                        att.name = onceOpenedMessages[folder_name][message_number].subject + '.eml'; 
     3800                                                        var idATT = JSON.stringify(att); 
     3801                                                        addAttachment( ID , idATT);                         
     3802                                                        var attach = {}; 
     3803                                                        attach.fileName = att.name 
     3804                                                        if(attach.fileName.length > 45) 
     3805                                                                        attach.fileName = attach.fileName.substr(0, 32) + " ... " + attach.fileName.substr(attach.fileName.length-9, attach.fileName.length); 
     3806 
     3807                                                        attach.fileSize = formatBytes(onceOpenedMessages[folder_name][message_number].size); 
     3808                                                        var upload = $(DataLayer.render("../prototype/modules/mail/templates/attachment_add_itemlist.ejs", {file : attach})); 
     3809                                                        upload.find('.status-upload').addClass('ui-icon ui-icon-check'); 
     3810                                                        upload.find('.in-progress').remove();  
     3811                                                        upload.append('<input type="hidden" name="fileId[]" value=\''+idATT+'\'/>'); 
     3812                                                         
     3813                                                        upload.find('.button.close').button({ 
     3814                                                                icons: { 
     3815                                                                                                primary: "ui-icon-close" 
     3816                                                                                }, 
     3817                                                                                text: false 
     3818                                                                }).click(function(){ 
     3819                                                                                var idAttach = $(this).parent().find('input[name="fileId[]"]').val(); 
     3820                                                                                fileUploadMSG.find(' .attachments-list').find('input[value="'+idAttach+'"]'); 
     3821                                                                                delAttachment(ID,idAttach);  
     3822                                                                                $(this).parent().remove(); 
     3823                                                        });      
     3824                                                         
     3825                                                        fileUploadMSG.find('.attachments-list').append(upload);    
     3826                                                } 
     3827                                        }); 
     3828                                }); 
     3829                                 
     3830                                jQuery('#message-attach-dialog').dialog('close'); 
     3831                                 
     3832                        }); 
     3833                        jQuery('#message-attach-cancel-btn').click(function(event){ 
     3834                                jQuery('#message-attach-dialog').dialog('close'); 
     3835                        });                      
     3836                }); 
     3837        }); 
     3838        /* 
     3839        content.find('[name="files[]"]').fileupload({ 
     3840                sequentialUploads: true,  
     3841                limitConcurrentUploads: 1, 
     3842                type: 'post', 
     3843                dataType : 'json', 
     3844                url: "../prototype/post.php", 
     3845                forceIframeTransport: true, 
     3846                dropZone : fileUploadMSG.find(".button").filter(".fileinput-button"), 
     3847                formData: function(form) { 
     3848                        return [ 
     3849                                { 
     3850                                        name : "mailAttachment[0][source]", 
     3851                                        value : "files0" 
     3852                                }, 
     3853                                { 
     3854                                        name : "mailAttachment[0][disposition]", 
     3855                                        value : $(form[0]['attDisposition'+$(form[0]['abaID']).val()]).val() 
     3856                                }, 
     3857                                { 
     3858                                        name: "MAX_FILE_SIZE", 
     3859                                        value : maxAttachmentSize 
     3860                                } 
     3861                        ]; 
     3862                },               
     3863                add: function (e, data) { 
     3864                        if(!maxAttachmentSize || data.files[0].size < maxAttachmentSize || is_ie) { 
     3865                                setTimeout(function() { 
     3866                    $('#attDisposition'+ID).val('attachment'); 
     3867                                        if(!data.fileInput){ 
     3868                                                data.fileInput = fileUploadMSG.find("input:file"); 
     3869                                                 
     3870                                                //fileUploadMSG.find("input:file").trigger("change.undefined"); 
     3871                                        } 
     3872                                        data.submit(); 
     3873                                }, 3000); 
     3874                        } 
     3875                }, 
     3876                done: function(e, data){ 
     3877                        if(!!data.result && data.result != "[]" ){ 
     3878                                var newAttach = data.result;                              
     3879                                if(!newAttach.mailAttachment.error){ 
     3880                                        if(newAttach.rollback !== false) 
     3881                                        { 
     3882                                                fileUploadMSG.find('.in-progress:first').parents('p').append('<input type="hidden" name="fileId[]" value="'+newAttach['mailAttachment'][0][0].id+'"/>').find('.status-upload').addClass('ui-icon ui-icon-check'); 
     3883                                                addAttachment(ID,newAttach['mailAttachment'][0][0].id); 
     3884                                        } 
     3885                                        else                              
     3886                                                fileUploadMSG.find('.in-progress:first').parents('p').find('.status-upload').append('Erro ao fazer upload!').addClass('message-attach-error');    
     3887                                }else{ 
     3888                                        fileUploadMSG.find('.in-progress:first').parents('p').find('.status-upload').append(newAttach.mailAttachment.error).addClass('message-attach-error');    
     3889                                } 
     3890                                 
     3891                        }else { 
     3892                                fileUploadMSG.find(' .progress.on-complete:first').parents('p').find('.status-upload').append('Erro ao fazer upload!').addClass('message-attach-error'); 
     3893                        } 
     3894            fileUploadMSG.find(' .in-progress:first').remove(); 
     3895                }, 
     3896                change: function (e, data) { 
     3897                        $.each(data.files, function (index, file) { 
     3898                                var attach = {}; 
     3899                                attach.fullFileName = file.name; 
     3900                                attach.fileName = file.name; 
     3901                                if(file.name.length > 50) 
     3902                                        attach.fileName = file.name.substr(0, 32) + " ... " + file.name.substr(file.name.length-9, file.name.length); 
     3903                                attach.fileSize = formatBytes(file.size); 
     3904                                if(maxAttachmentSize && file.size > maxAttachmentSize) 
     3905                                        attach.error = 'Tamanho de arquivo nao permitido!!' 
     3906                                 
     3907                                var upload = $(DataLayer.render("../prototype/modules/mail/templates/attachment_add_itemlist.ejs", {file : attach}));                            
     3908                                upload.find('.button.close').button({ 
     3909                                        icons: { 
     3910                                                primary: "ui-icon-close" 
     3911                                        }, 
     3912                                        text: false 
     3913                                }).click(function(){ 
     3914                                        var idAttach = $(this).parent().find('input[name="fileId[]"]').val(); 
     3915                                        fileUploadMSG.find(' .attachments-list').find('input[value="'+idAttach+'"]').remove(); 
     3916                                        delAttachment(ID, idAttach) 
     3917                                        $(this).parent().remove(); 
     3918                                }); 
     3919                                 
     3920                                fileUploadMSG.find('.attachments-list').append(upload); 
     3921 
     3922                                if(!maxAttachmentSize || file.size < maxAttachmentSize){ 
     3923                                        fileUploadMSG.find('.fileinput-button.new').append(data.fileInput[0]).removeClass('new'); 
     3924                                        fileUploadMSG.find('.attachments-list').find('[type=file]').addClass('hidden');  
     3925                                }else 
     3926                                        fileUploadMSG.find(' .fileinput-button.new').removeClass('new'); 
     3927 
     3928                })} 
     3929        }) 
     3930        fileUploadMSG.find('[name="files[]"]').css({"height" : "20px", "width": "100px", "border-width": "0 0 0px 0px", "-moz-transform" : "none","-o-transform" : 'none'}); 
     3931        //fileUploadMSG.unbind('dragover.undefined'); 
    37683932                 
    37693933       fileUploadMSG.find("span.message-attach-link").click(function(event){ 
     
    38333997 
    38343998        }); 
     3999        */ 
    38354000//   style="width: 100px; height: 20px;"/    
    38364001        //$('[name="files[]"]').css({"height" : "20px", "width": "100px", "border-width": "0 0 0px 0px", "cursor" : "pointer"});// "display": "none" 
  • trunk/prototype/modules/mail/templates/attachment.ejs

    r6071 r6107  
    11<div id="fileupload_msg<%=data.ID%>" class="fileupload" style="margin : 15px 0px -15px -10px;"> 
    2   <div class="row fileupload-buttonbar"> 
    3       <div class="button-files-upload"> 
    4               <span class="button small btn-success fileinput-button ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role="button"> 
    5                   <span class="ui-button-text" title="Clique para anexar um arquivo ou arraste diretamente o arquivo sobre este botão"> 
    6                       <span><i class="icon-plus icon-white"></i>Anexar arquivos</span> 
    7                       <input type="file" name="files[]" multiple=""> 
    8                   </span> 
    9               </span>  
    10       </div>     
    11  
    12      <span tabindex="-1" class="message-attach-link button small ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role="button"><span class="icon-plus ui-button-text">Anexar mensagens</span></span> 
    13     </div> 
    14       
    15          <div class="files-list"> 
    16             <ul class="attachments-list"></ul> 
    17          </div> 
    18         <br /> 
     2        <div class="row fileupload-buttonbar"> 
     3                <div class="button-files-upload"> 
     4                        <<%= is_webkit ? 'button' : 'span style="height: 22px;"' %>  class="fileinput-button button small"> 
     5                                <span style="margin-top: 4px;">Anexar arquivos</span> 
     6                                <INPUT type="file" id="fileInput<%=data.ID%>" name="files[]" multiple style="cursor:pointer;"></INPUT> 
     7                        </<%= is_webkit ? 'button' : 'span' %>> 
     8                        <button class="message-attach-link button small"> 
     9                                <span>Anexar mensagens</span> 
     10                        </button> 
     11                </div> 
     12        </div> 
     13        <br /> 
     14        <div class="files-list" style="margin: 5px; padding: 5px;"> 
     15                <ul class="attachments-list"></ul> 
     16        </div> 
     17        <br /> 
    1918</div> 
  • trunk/prototype/modules/mail/templates/attachment_add_itemlist.ejs

    r5767 r6107  
     1<li style="list-style : none;"> 
    12        <p class="input-group archive-info" style="margin: 0px 0 !important; height: 17px">              
    23                <span title="<%=data.file.fullFileName%>" class="archive-attach name"><%=data.file.fileName%></span> 
    34                <span class="archive-attach size"><%=data.file.fileSize%></span> 
    4                 <button type="button" class="button close tiny upload delete-upload" title="Deletar">Deletar</button> 
     5                <button type="button" style="margin-bottom: -4px;" class="button close tiny upload delete-upload" title="Deletar">Deletar</button> 
    56                <span class="status-upload"></span> 
    67                <%if(data.file.error){%> 
     
    1415                 
    1516    </p> 
     17</li> 
  • trunk/prototype/modules/mail/templates/new_message.ejs

    r6060 r6107  
    119119                                </td> 
    120120                                <td class="value"> 
    121                                         <div id="message-attach-dialog" title="'<%=get_lang("Select messages to attach...")%>" style="clear: both;")>&nbsp;</div> 
     121                                        <div id="message-attach-dialog" title="'<%=get_lang("Select messages to attach...")%>" style="clear: both; display:none;")>&nbsp;</div> 
    122122                                </td> 
    123123                        </tr> 
  • trunk/prototype/plugins/fileupload/jquery.fileupload-ui.css

    r5341 r6107  
    11@charset 'UTF-8'; 
    22/* 
    3  * jQuery File Upload UI Plugin CSS 5.0.6 
     3 * jQuery File Upload UI Plugin CSS 6.3 
    44 * https://github.com/blueimp/jQuery-File-Upload 
    55 * 
     
    88 * 
    99 * Licensed under the MIT license: 
    10  * http://creativecommons.org/licenses/MIT/ 
     10 * http://www.opensource.org/licenses/MIT 
    1111 */ 
    1212 
    13 .fileupload-buttonbar .ui-button input { 
     13.fileinput-button { 
     14  position: relative; 
     15  overflow: hidden; 
     16  float: left; 
     17  margin-right: 4px; 
     18} 
     19.fileinput-button input { 
    1420  position: absolute; 
    1521  top: 0; 
     
    2026  opacity: 0; 
    2127  filter: alpha(opacity=0); 
    22   -o-transform: translate(250px, -50px) scale(1); 
    2328  -moz-transform: translate(-300px, 0) scale(4); 
    2429  direction: ltr; 
    2530  cursor: pointer; 
    2631} 
    27  
    28 .fileinput-button { 
    29   overflow: hidden; 
     32.fileupload-buttonbar .btn, 
     33.fileupload-buttonbar .toggle { 
     34  margin-bottom: 5px; 
     35} 
     36.files .progress { 
     37  width: 200px; 
     38} 
     39.progress-animated .bar { 
     40  background: url(../img/progressbar.gif) !important; 
     41  filter: none; 
     42} 
     43.fileupload-loading { 
     44  position: absolute; 
     45  left: 50%; 
     46  width: 128px; 
     47  height: 128px; 
     48  background: url(../img/loading.gif) center no-repeat; 
     49  display: none; 
     50} 
     51.fileupload-processing .fileupload-loading { 
     52  display: block; 
    3053} 
    3154 
    3255/* Fix for IE 6: */ 
    3356*html .fileinput-button { 
    34   padding: 2px 0; 
     57  line-height: 22px; 
     58  margin: 1px -3px 0 0; 
    3559} 
    3660 
    3761/* Fix for IE 7: */ 
    3862*+html .fileinput-button { 
    39   padding: 2px 0; 
     63  margin: 1px 0 0 0; 
    4064} 
    4165 
    42 .fileupload-buttonbar { 
    43   padding: 0.2em 0.4em; 
     66@media (max-width: 480px) { 
     67  .files .btn span { 
     68    display: none; 
     69  } 
     70  .files .preview * { 
     71    width: 40px; 
     72  } 
     73  .files .name * { 
     74    width: 80px; 
     75    display: inline-block; 
     76    word-wrap: break-word; 
     77  } 
     78  .files .progress { 
     79    width: 20px; 
     80  } 
     81  .files .delete { 
     82    width: 60px; 
     83  } 
    4484} 
    45  
    46 .fileupload-buttonbar .ui-button { 
    47   vertical-align: middle; 
    48 } 
    49  
    50 .fileupload-content { 
    51   padding: 0.2em 0.4em; 
    52   border-top-width: 0; 
    53 } 
    54  
    55 .fileupload-content .ui-progressbar { 
    56   width: 200px; 
    57   height: 20px; 
    58 } 
    59  
    60 .fileupload-content .ui-progressbar-value { 
    61   background: url(pbar-ani.gif); 
    62 } 
    63  
    64 .fileupload-content .fileupload-progressbar { 
    65   width: 400px; 
    66   margin: 10px 0; 
    67 } 
    68  
    69 .files { 
    70   margin: 10px 0; 
    71   border-collapse: collapse; 
    72 } 
    73  
    74 .files td { 
    75   padding: 5px; 
    76   border-spacing: 5px; 
    77 } 
    78  
    79 .files img { 
    80   border: none; 
    81 } 
    82  
    83 .files .name { 
    84   padding: 0 10px; 
    85 } 
    86  
    87 .files .size { 
    88   padding: 0 10px 0 0; 
    89   text-align: right; 
    90   white-space: nowrap; 
    91 } 
    92  
    93 .ui-state-disabled .ui-state-disabled { 
    94   opacity: 1; 
    95   filter: alpha(opacity=100); 
    96 } 
    97  
    98 .ui-state-disabled input { 
    99   cursor: default; 
    100 } 
  • trunk/prototype/plugins/fileupload/jquery.fileupload-ui.js

    r5341 r6107  
    11/* 
    2  * jQuery File Upload User Interface Plugin 5.0.16 
     2 * jQuery File Upload User Interface Plugin 6.7 
    33 * https://github.com/blueimp/jQuery-File-Upload 
    44 * 
     
    77 * 
    88 * Licensed under the MIT license: 
    9  * http://creativecommons.org/licenses/MIT/ 
     9 * http://www.opensource.org/licenses/MIT 
    1010 */ 
    1111 
    1212/*jslint nomen: true, unparam: true, regexp: true */ 
    13 /*global window, document, URL, webkitURL, FileReader, jQuery */ 
    14  
    15 (function ($) { 
     13/*global define, window, document, URL, webkitURL, FileReader */ 
     14 
     15(function (factory) { 
    1616    'use strict'; 
    17      
    18     // The UI version extends the basic fileupload widget and adds 
    19     // a complete user interface based on the given upload/download 
    20     // templates. 
    21     $.widget('blueimpUI.fileupload', $.blueimp.fileupload, { 
    22          
     17    if (typeof define === 'function' && define.amd) { 
     18        // Register as an anonymous AMD module: 
     19        define([ 
     20            'jquery', 
     21            'tmpl', 
     22            'load-image', 
     23            './jquery.fileupload-fp' 
     24        ], factory); 
     25    } else { 
     26        // Browser globals: 
     27        factory( 
     28            window.jQuery, 
     29            window.tmpl, 
     30            window.loadImage 
     31        ); 
     32    } 
     33}(function ($, tmpl, loadImage) { 
     34    'use strict'; 
     35 
     36    // The UI version extends the FP (file processing) version or the basic 
     37    // file upload widget and adds complete user interface interaction: 
     38    var parentWidget = ($.blueimpFP || $.blueimp).fileupload; 
     39    $.widget('blueimpUI.fileupload', parentWidget, { 
     40 
    2341        options: { 
    2442            // By default, files added to the widget are uploaded as soon 
     
    3250            maxFileSize: undefined, 
    3351            // The minimum allowed file size: 
    34             minFileSize: 1, 
     52            minFileSize: undefined, 
    3553            // The regular expression for allowed file types, matches 
    3654            // against either file type or file name: 
     
    3856            // The regular expression to define for which files a preview 
    3957            // image is shown, matched against the file type: 
    40             previewFileTypes: /^image\/(gif|jpeg|png)$/, 
     58            previewSourceFileTypes: /^image\/(gif|jpeg|png)$/, 
     59            // The maximum file size of images that are to be displayed as preview: 
     60            previewSourceMaxFileSize: 5000000, // 5MB 
    4161            // The maximum width of the preview images: 
    4262            previewMaxWidth: 80, 
     
    4767            // to always display preview images as img elements: 
    4868            previewAsCanvas: true, 
    49             // The file upload template that is given as first argument to the 
    50             // jQuery.tmpl method to render the file uploads: 
    51             uploadTemplate: $('#template-upload'), 
    52             // The file download template, that is given as first argument to the 
    53             // jQuery.tmpl method to render the file downloads: 
    54             downloadTemplate: $('#template-download'), 
     69            // The ID of the upload template: 
     70            uploadTemplateId: 'template-upload', 
     71            // The ID of the download template: 
     72            downloadTemplateId: 'template-download', 
     73            // The container for the list of files. If undefined, it is set to 
     74            // an element with class "files" inside of the widget element: 
     75            filesContainer: undefined, 
     76            // By default, files are appended to the files container. 
     77            // Set the following option to true, to prepend files instead: 
     78            prependFiles: false, 
    5579            // The expected data type of the upload response, sets the dataType 
    5680            // option of the $.ajax upload requests: 
    5781            dataType: 'json', 
    58              
     82 
    5983            // The add callback is invoked as soon as files are added to the fileupload 
    6084            // widget (via file input selection, drag & drop or add API call). 
    6185            // See the basic file upload widget for more information: 
    6286            add: function (e, data) { 
    63                 var that = $(this).data('fileupload'); 
    64                 that._adjustMaxNumberOfFiles(-data.files.length); 
    65                 data.isAdjusted = true; 
    66                 data.isValidated = that._validate(data.files); 
    67                 data.context = that._renderUpload(data.files) 
    68                     .appendTo($(this).find('.files')).fadeIn(function () { 
    69                         // Fix for IE7 and lower: 
    70                         $(this).show(); 
    71                     }).data('data', data); 
    72                 if ((that.options.autoUpload || data.autoUpload) && 
    73                         data.isValidated) { 
    74                     data.jqXHR = data.submit(); 
    75                 } 
     87                var that = $(this).data('fileupload'), 
     88                    options = that.options, 
     89                    files = data.files; 
     90                $(this).fileupload('process', data).done(function () { 
     91                    that._adjustMaxNumberOfFiles(-files.length); 
     92                    data.isAdjusted = true; 
     93                    data.files.valid = data.isValidated = that._validate(files); 
     94                    data.context = that._renderUpload(files).data('data', data); 
     95                    options.filesContainer[ 
     96                        options.prependFiles ? 'prepend' : 'append' 
     97                    ](data.context); 
     98                    that._renderPreviews(files, data.context); 
     99                    that._forceReflow(data.context); 
     100                    that._transition(data.context).done( 
     101                        function () { 
     102                            if ((that._trigger('added', e, data) !== false) && 
     103                                    (options.autoUpload || data.autoUpload) && 
     104                                    data.autoUpload !== false && data.isValidated) { 
     105                                data.submit(); 
     106                            } 
     107                        } 
     108                    ); 
     109                }); 
    76110            }, 
    77111            // Callback for the start of each file upload request: 
    78112            send: function (e, data) { 
     113                var that = $(this).data('fileupload'); 
    79114                if (!data.isValidated) { 
    80                     var that = $(this).data('fileupload'); 
    81115                    if (!data.isAdjusted) { 
    82116                        that._adjustMaxNumberOfFiles(-data.files.length); 
     
    91125                    // In lack of an indeterminate progress bar, we set 
    92126                    // the progress to 100%, showing the full animated bar: 
    93                     data.context.find('.ui-progressbar').progressbar( 
    94                         'value', 
    95                         parseInt(100, 10) 
    96                     ); 
    97                 } 
     127                    data.context 
     128                        .find('.progress').addClass( 
     129                            !$.support.transition && 'progress-animated' 
     130                        ) 
     131                        .find('.bar').css( 
     132                            'width', 
     133                            parseInt(100, 10) + '%' 
     134                        ); 
     135                } 
     136                return that._trigger('sent', e, data); 
    98137            }, 
    99138            // Callback for successful uploads: 
    100139            done: function (e, data) { 
    101                 var that = $(this).data('fileupload'); 
     140                var that = $(this).data('fileupload'), 
     141                    template, 
     142                    preview; 
    102143                if (data.context) { 
    103144                    data.context.each(function (index) { 
     
    107148                            that._adjustMaxNumberOfFiles(1); 
    108149                        } 
    109                         $(this).fadeOut(function () { 
    110                             that._renderDownload([file]) 
    111                                 .css('display', 'none') 
    112                                 .replaceAll(this) 
    113                                 .fadeIn(function () { 
    114                                     // Fix for IE7 and lower: 
    115                                     $(this).show(); 
    116                                 }); 
    117                         }); 
     150                        that._transition($(this)).done( 
     151                            function () { 
     152                                var node = $(this); 
     153                                template = that._renderDownload([file]) 
     154                                    .css('height', node.height()) 
     155                                    .replaceAll(node); 
     156                                that._forceReflow(template); 
     157                                that._transition(template).done( 
     158                                    function () { 
     159                                        data.context = $(this); 
     160                                        that._trigger('completed', e, data); 
     161                                    } 
     162                                ); 
     163                            } 
     164                        ); 
    118165                    }); 
    119166                } else { 
    120                     that._renderDownload(data.result) 
    121                         .css('display', 'none') 
    122                         .appendTo($(this).find('.files')) 
    123                         .fadeIn(function () { 
    124                             // Fix for IE7 and lower: 
    125                             $(this).show(); 
    126                         }); 
     167                    template = that._renderDownload(data.result) 
     168                        .appendTo(that.options.filesContainer); 
     169                    that._forceReflow(template); 
     170                    that._transition(template).done( 
     171                        function () { 
     172                            data.context = $(this); 
     173                            that._trigger('completed', e, data); 
     174                        } 
     175                    ); 
    127176                } 
    128177            }, 
    129178            // Callback for failed (abort or error) uploads: 
    130179            fail: function (e, data) { 
    131                 var that = $(this).data('fileupload'); 
     180                var that = $(this).data('fileupload'), 
     181                    template; 
    132182                that._adjustMaxNumberOfFiles(data.files.length); 
    133183                if (data.context) { 
    134184                    data.context.each(function (index) { 
    135                         $(this).fadeOut(function () { 
    136                             if (data.errorThrown !== 'abort') { 
    137                                 var file = data.files[index]; 
    138                                 file.error = file.error || data.errorThrown 
    139                                     || true; 
    140                                 that._renderDownload([file]) 
    141                                     .css('display', 'none') 
    142                                     .replaceAll(this) 
    143                                     .fadeIn(function () { 
    144                                         // Fix for IE7 and lower: 
    145                                         $(this).show(); 
    146                                     }); 
    147                             } else { 
    148                                 data.context.remove(); 
    149                             } 
    150                         }); 
     185                        if (data.errorThrown !== 'abort') { 
     186                            var file = data.files[index]; 
     187                            file.error = file.error || data.errorThrown || 
     188                                true; 
     189                            that._transition($(this)).done( 
     190                                function () { 
     191                                    var node = $(this); 
     192                                    template = that._renderDownload([file]) 
     193                                        .replaceAll(node); 
     194                                    that._forceReflow(template); 
     195                                    that._transition(template).done( 
     196                                        function () { 
     197                                            data.context = $(this); 
     198                                            that._trigger('failed', e, data); 
     199                                        } 
     200                                    ); 
     201                                } 
     202                            ); 
     203                        } else { 
     204                            that._transition($(this)).done( 
     205                                function () { 
     206                                    $(this).remove(); 
     207                                    that._trigger('failed', e, data); 
     208                                } 
     209                            ); 
     210                        } 
    151211                    }); 
    152212                } else if (data.errorThrown !== 'abort') { 
    153213                    that._adjustMaxNumberOfFiles(-data.files.length); 
    154214                    data.context = that._renderUpload(data.files) 
    155                         .css('display', 'none') 
    156                         .appendTo($(this).find('.files')) 
    157                         .fadeIn(function () { 
    158                             // Fix for IE7 and lower: 
    159                             $(this).show(); 
    160                         }).data('data', data); 
     215                        .appendTo(that.options.filesContainer) 
     216                        .data('data', data); 
     217                    that._forceReflow(data.context); 
     218                    that._transition(data.context).done( 
     219                        function () { 
     220                            data.context = $(this); 
     221                            that._trigger('failed', e, data); 
     222                        } 
     223                    ); 
     224                } else { 
     225                    that._trigger('failed', e, data); 
    161226                } 
    162227            }, 
     
    164229            progress: function (e, data) { 
    165230                if (data.context) { 
    166                     data.context.find('.ui-progressbar').progressbar( 
    167                         'value', 
    168                         parseInt(data.loaded / data.total * 100, 10) 
     231                    data.context.find('.progress .bar').css( 
     232                        'width', 
     233                        parseInt(data.loaded / data.total * 100, 10) + '%' 
    169234                    ); 
    170235                } 
     
    172237            // Callback for global upload progress events: 
    173238            progressall: function (e, data) { 
    174                 $(this).find('.fileupload-progressbar').progressbar( 
    175                     'value', 
    176                     parseInt(data.loaded / data.total * 100, 10) 
     239                $(this).find('.fileupload-buttonbar .progress .bar').css( 
     240                    'width', 
     241                    parseInt(data.loaded / data.total * 100, 10) + '%' 
    177242                ); 
    178243            }, 
    179244            // Callback for uploads start, equivalent to the global ajaxStart event: 
    180             start: function () { 
    181                 $(this).find('.fileupload-progressbar') 
    182                     .progressbar('value', 0).fadeIn(); 
     245            start: function (e) { 
     246                var that = $(this).data('fileupload'); 
     247                that._transition($(this).find('.fileupload-buttonbar .progress')).done( 
     248                    function () { 
     249                        that._trigger('started', e); 
     250                    } 
     251                ); 
    183252            }, 
    184253            // Callback for uploads stop, equivalent to the global ajaxStop event: 
    185             stop: function () { 
    186                 $(this).find('.fileupload-progressbar').fadeOut(); 
     254            stop: function (e) { 
     255                var that = $(this).data('fileupload'); 
     256                that._transition($(this).find('.fileupload-buttonbar .progress')).done( 
     257                    function () { 
     258                        $(this).find('.bar').css('width', '0%'); 
     259                        that._trigger('stopped', e); 
     260                    } 
     261                ); 
    187262            }, 
    188263            // Callback for file deletion: 
     
    190265                var that = $(this).data('fileupload'); 
    191266                if (data.url) { 
    192                     $.ajax(data) 
    193                         .success(function () { 
    194                             that._adjustMaxNumberOfFiles(1); 
    195                             $(this).fadeOut(function () { 
    196                                 $(this).remove(); 
    197                             }); 
    198                         }); 
    199                 } else { 
    200                     that._adjustMaxNumberOfFiles(1); 
    201                     data.context.fadeOut(function () { 
     267                    $.ajax(data); 
     268                } 
     269                that._adjustMaxNumberOfFiles(1); 
     270                that._transition(data.context).done( 
     271                    function () { 
    202272                        $(this).remove(); 
    203                     }); 
    204                 } 
    205             } 
    206         }, 
    207  
    208         // Scales the given image (img HTML element) 
    209         // using the given options. 
    210         // Returns a canvas object if the canvas option is true 
    211         // and the browser supports canvas, else the scaled image: 
    212         _scaleImage: function (img, options) { 
    213             options = options || {}; 
    214             var canvas = document.createElement('canvas'), 
    215                 scale = Math.min( 
    216                     (options.maxWidth || img.width) / img.width, 
    217                     (options.maxHeight || img.height) / img.height 
     273                        that._trigger('destroyed', e, data); 
     274                    } 
    218275                ); 
    219             if (scale >= 1) { 
    220                 scale = Math.max( 
    221                     (options.minWidth || img.width) / img.width, 
    222                     (options.minHeight || img.height) / img.height 
    223                 ); 
    224             } 
    225             img.width = parseInt(img.width * scale, 10); 
    226             img.height = parseInt(img.height * scale, 10); 
    227             if (!options.canvas || !canvas.getContext) { 
    228                 return img; 
    229             } 
    230             canvas.width = img.width; 
    231             canvas.height = img.height; 
    232             canvas.getContext('2d') 
    233                 .drawImage(img, 0, 0, img.width, img.height); 
    234             return canvas; 
    235         }, 
    236  
    237         _createObjectURL: function (file) { 
    238             var undef = 'undefined', 
    239                 urlAPI = (typeof window.createObjectURL !== undef && window) || 
    240                     (typeof URL !== undef && URL) || 
    241                     (typeof webkitURL !== undef && webkitURL); 
    242             return urlAPI ? urlAPI.createObjectURL(file) : false; 
    243         }, 
    244          
    245         _revokeObjectURL: function (url) { 
    246             var undef = 'undefined', 
    247                 urlAPI = (typeof window.revokeObjectURL !== undef && window) || 
    248                     (typeof URL !== undef && URL) || 
    249                     (typeof webkitURL !== undef && webkitURL); 
    250             return urlAPI ? urlAPI.revokeObjectURL(url) : false; 
    251         }, 
    252  
    253         // Loads a given File object via FileReader interface, 
    254         // invokes the callback with a data url: 
    255         _loadFile: function (file, callback) { 
    256             if (typeof FileReader !== 'undefined' && 
    257                     FileReader.prototype.readAsDataURL) { 
    258                 var fileReader = new FileReader(); 
    259                 fileReader.onload = function (e) { 
    260                     callback(e.target.result); 
    261                 }; 
    262                 fileReader.readAsDataURL(file); 
    263                 return true; 
    264             } 
    265             return false; 
    266         }, 
    267  
    268         // Loads an image for a given File object. 
    269         // Invokes the callback with an img or optional canvas 
    270         // element (if supported by the browser) as parameter: 
    271         _loadImage: function (file, callback, options) { 
    272             var that = this, 
    273                 url, 
    274                 img; 
    275             if (!options || !options.fileTypes || 
    276                     options.fileTypes.test(file.type)) { 
    277                 url = this._createObjectURL(file); 
    278                 img = $('<img>').bind('load', function () { 
    279                     $(this).unbind('load'); 
    280                     that._revokeObjectURL(url); 
    281                     callback(that._scaleImage(img[0], options)); 
    282                 }); 
    283                 if (url) { 
    284                     img.prop('src', url); 
    285                 } else { 
    286                     this._loadFile(file, function (url) { 
    287                         img.prop('src', url); 
    288                     }); 
    289                 } 
    290276            } 
    291277        }, 
     
    296282            var link = $(this), 
    297283                url = link.prop('href'), 
    298                 name = decodeURIComponent(url.split('/').pop()) 
    299                     .replace(/:/g, '-'), 
     284                name = link.prop('download'), 
    300285                type = 'application/octet-stream'; 
    301286            link.bind('dragstart', function (e) { 
     
    320305        }, 
    321306 
    322         _formatFileSize: function (file) { 
    323             if (typeof file.size !== 'number') { 
     307        _formatFileSize: function (bytes) { 
     308            if (typeof bytes !== 'number') { 
    324309                return ''; 
    325310            } 
    326             if (file.size >= 1000000000) { 
    327                 return (file.size / 1000000000).toFixed(2) + ' GB'; 
    328             } 
    329             if (file.size >= 1000000) { 
    330                 return (file.size / 1000000).toFixed(2) + ' MB'; 
    331             } 
    332             return (file.size / 1000).toFixed(2) + ' KB'; 
     311            if (bytes >= 1000000000) { 
     312                return (bytes / 1000000000).toFixed(2) + ' GB'; 
     313            } 
     314            if (bytes >= 1000000) { 
     315                return (bytes / 1000000).toFixed(2) + ' MB'; 
     316            } 
     317            return (bytes / 1000).toFixed(2) + ' KB'; 
    333318        }, 
    334319 
     
    373358        }, 
    374359 
    375         _uploadTemplateHelper: function (file) { 
    376             file.sizef = this._formatFileSize(file); 
    377             return file; 
    378         }, 
    379  
    380         _renderUploadTemplate: function (files) { 
    381             var that = this; 
    382             return $.tmpl( 
    383                 this.options.uploadTemplate, 
    384                 $.map(files, function (file) { 
    385                     return that._uploadTemplateHelper(file); 
    386                 }) 
    387             ); 
    388         }, 
    389  
    390         _renderUpload: function (files) { 
     360        _renderTemplate: function (func, files) { 
     361            if (!func) { 
     362                return $(); 
     363            } 
     364            var result = func({ 
     365                files: files, 
     366                formatFileSize: this._formatFileSize, 
     367                options: this.options 
     368            }); 
     369            if (result instanceof $) { 
     370                return result; 
     371            } 
     372            return $(this.options.templatesContainer).html(result).children(); 
     373        }, 
     374 
     375        _renderPreview: function (file, node) { 
    391376            var that = this, 
    392377                options = this.options, 
    393                 tmpl = this._renderUploadTemplate(files), 
    394                 isValidated = this._validate(files); 
    395             if (!(tmpl instanceof $)) { 
    396                 return $(); 
    397             } 
    398             tmpl.css('display', 'none'); 
    399             // .slice(1).remove().end().first() removes all but the first 
    400             // element and selects only the first for the jQuery collection: 
    401             tmpl.find('.progress div').slice( 
    402                 isValidated ? 1 : 0 
    403             ).remove().end().first() 
    404                 .progressbar(); 
    405             tmpl.find('.start button').slice( 
    406                 this.options.autoUpload || !isValidated ? 0 : 1 
    407             ).remove().end().first() 
    408                 .button({ 
    409                     text: false, 
    410                     icons: {primary: 'ui-icon-circle-arrow-e'} 
    411                 }); 
    412             tmpl.find('.cancel button').slice(1).remove().end().first() 
    413                 .button({ 
    414                     text: false, 
    415                     icons: {primary: 'ui-icon-cancel'} 
    416                 }); 
    417             tmpl.find('.preview').each(function (index, node) { 
    418                 that._loadImage( 
    419                     files[index], 
    420                     function (img) { 
    421                         $(img).hide().appendTo(node).fadeIn(); 
    422                     }, 
    423                     { 
    424                         maxWidth: options.previewMaxWidth, 
    425                         maxHeight: options.previewMaxHeight, 
    426                         fileTypes: options.previewFileTypes, 
    427                         canvas: options.previewAsCanvas 
     378                dfd = $.Deferred(); 
     379            return ((loadImage && loadImage( 
     380                file, 
     381                function (img) { 
     382                    node.append(img); 
     383                    that._forceReflow(node); 
     384                    that._transition(node).done(function () { 
     385                        dfd.resolveWith(node); 
     386                    }); 
     387                    if (!$.contains(document.body, node[0])) { 
     388                        // If the element is not part of the DOM, 
     389                        // transition events are not triggered, 
     390                        // so we have to resolve manually: 
     391                        dfd.resolveWith(node); 
    428392                    } 
    429                 ); 
     393                }, 
     394                { 
     395                    maxWidth: options.previewMaxWidth, 
     396                    maxHeight: options.previewMaxHeight, 
     397                    canvas: options.previewAsCanvas 
     398                } 
     399            )) || dfd.resolveWith(node)) && dfd; 
     400        }, 
     401 
     402        _renderPreviews: function (files, nodes) { 
     403            var that = this, 
     404                options = this.options; 
     405            nodes.find('.preview span').each(function (index, element) { 
     406                var file = files[index]; 
     407                if (options.previewSourceFileTypes.test(file.type) && 
     408                        ($.type(options.previewSourceMaxFileSize) !== 'number' || 
     409                        file.size < options.previewSourceMaxFileSize)) { 
     410                    that._processingQueue = that._processingQueue.pipe(function () { 
     411                        var dfd = $.Deferred(); 
     412                        that._renderPreview(file, $(element)).done( 
     413                            function () { 
     414                                dfd.resolveWith(that); 
     415                            } 
     416                        ); 
     417                        return dfd.promise(); 
     418                    }); 
     419                } 
    430420            }); 
    431             return tmpl; 
    432         }, 
    433  
    434         _downloadTemplateHelper: function (file) { 
    435             file.sizef = this._formatFileSize(file); 
    436             return file; 
    437         }, 
    438  
    439         _renderDownloadTemplate: function (files) { 
    440             var that = this; 
    441             return $.tmpl( 
     421            return this._processingQueue; 
     422        }, 
     423 
     424        _renderUpload: function (files) { 
     425            return this._renderTemplate( 
     426                this.options.uploadTemplate, 
     427                files 
     428            ); 
     429        }, 
     430 
     431        _renderDownload: function (files) { 
     432            return this._renderTemplate( 
    442433                this.options.downloadTemplate, 
    443                 $.map(files, function (file) { 
    444                     return that._downloadTemplateHelper(file); 
    445                 }) 
    446             ); 
    447         }, 
    448          
    449         _renderDownload: function (files) { 
    450             var tmpl = this._renderDownloadTemplate(files); 
    451             if (!(tmpl instanceof $)) { 
    452                 return $(); 
    453             } 
    454             tmpl.css('display', 'none'); 
    455             tmpl.find('.delete button').button({ 
    456                 text: false, 
    457                 icons: {primary: 'ui-icon-trash'} 
    458             }); 
    459             tmpl.find('a').each(this._enableDragToDesktop); 
    460             return tmpl; 
    461         }, 
    462          
     434                files 
     435            ).find('a[download]').each(this._enableDragToDesktop).end(); 
     436        }, 
     437 
    463438        _startHandler: function (e) { 
    464439            e.preventDefault(); 
    465             var tmpl = $(this).closest('.template-upload'), 
    466                 data = tmpl.data('data'); 
    467             if (data && data.submit && !data.jqXHR) { 
    468                 data.jqXHR = data.submit(); 
    469                 $(this).fadeOut(); 
    470             } 
    471         }, 
    472          
     440            var button = $(this), 
     441                template = button.closest('.template-upload'), 
     442                data = template.data('data'); 
     443            if (data && data.submit && !data.jqXHR && data.submit()) { 
     444                button.prop('disabled', true); 
     445            } 
     446        }, 
     447 
    473448        _cancelHandler: function (e) { 
    474449            e.preventDefault(); 
    475             var tmpl = $(this).closest('.template-upload'), 
    476                 data = tmpl.data('data') || {}; 
     450            var template = $(this).closest('.template-upload'), 
     451                data = template.data('data') || {}; 
    477452            if (!data.jqXHR) { 
    478453                data.errorThrown = 'abort'; 
     
    482457            } 
    483458        }, 
    484          
     459 
    485460        _deleteHandler: function (e) { 
    486461            e.preventDefault(); 
     
    489464                context: button.closest('.template-download'), 
    490465                url: button.attr('data-url'), 
    491                 type: button.attr('data-type'), 
     466                type: button.attr('data-type') || 'DELETE', 
    492467                dataType: e.data.fileupload.options.dataType 
    493468            }); 
    494469        }, 
    495          
    496         _initEventHandlers: function () { 
    497             $.blueimp.fileupload.prototype._initEventHandlers.call(this); 
    498             var filesList = this.element.find('.files'), 
    499                 eventData = {fileupload: this}; 
    500             filesList.find('.start button') 
    501                 .live( 
    502                     'click.' + this.options.namespace, 
    503                     eventData, 
    504                     this._startHandler 
    505                 ); 
    506             filesList.find('.cancel button') 
    507                 .live( 
    508                     'click.' + this.options.namespace, 
    509                     eventData, 
    510                     this._cancelHandler 
    511                 ); 
    512             filesList.find('.delete button') 
    513                 .live( 
    514                     'click.' + this.options.namespace, 
    515                     eventData, 
    516                     this._deleteHandler 
    517                 ); 
    518         }, 
    519          
    520         _destroyEventHandlers: function () { 
    521             var filesList = this.element.find('.files'); 
    522             filesList.find('.start button') 
    523                 .die('click.' + this.options.namespace); 
    524             filesList.find('.cancel button') 
    525                 .die('click.' + this.options.namespace); 
    526             filesList.find('.delete button') 
    527                 .die('click.' + this.options.namespace); 
    528             $.blueimp.fileupload.prototype._destroyEventHandlers.call(this); 
    529         }, 
    530  
    531         _initFileUploadButtonBar: function () { 
     470 
     471        _forceReflow: function (node) { 
     472            this._reflow = $.support.transition && 
     473                node.length && node[0].offsetWidth; 
     474        }, 
     475 
     476        _transition: function (node) { 
     477            var that = this, 
     478                dfd = $.Deferred(); 
     479            if ($.support.transition && node.hasClass('fade')) { 
     480                node.bind( 
     481                    $.support.transition.end, 
     482                    function (e) { 
     483                        // Make sure we don't respond to other transitions events 
     484                        // in the container element, e.g. from button elements: 
     485                        if (e.target === node[0]) { 
     486                            node.unbind($.support.transition.end); 
     487                            dfd.resolveWith(node); 
     488                        } 
     489                    } 
     490                ).toggleClass('in'); 
     491            } else { 
     492                node.toggleClass('in'); 
     493                dfd.resolveWith(node); 
     494            } 
     495            return dfd; 
     496        }, 
     497 
     498        _initButtonBarEventHandlers: function () { 
    532499            var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'), 
    533                 filesList = this.element.find('.files'), 
     500                filesList = this.options.filesContainer, 
    534501                ns = this.options.namespace; 
    535             fileUploadButtonBar 
    536                 .addClass('ui-widget-header ui-corner-top'); 
    537             this.element.find('.fileinput-button').each(function () { 
    538                 var fileInput = $(this).find('input:file').detach(); 
    539                 $(this).button({icons: {primary: 'ui-icon-plusthick'}}) 
    540                     .append(fileInput); 
    541             }); 
    542502            fileUploadButtonBar.find('.start') 
    543                 .button({icons: {primary: 'ui-icon-circle-arrow-e'}}) 
    544503                .bind('click.' + ns, function (e) { 
    545504                    e.preventDefault(); 
     
    547506                }); 
    548507            fileUploadButtonBar.find('.cancel') 
    549                 .button({icons: {primary: 'ui-icon-cancel'}}) 
    550508                .bind('click.' + ns, function (e) { 
    551509                    e.preventDefault(); 
     
    553511                }); 
    554512            fileUploadButtonBar.find('.delete') 
    555                 .button({icons: {primary: 'ui-icon-trash'}}) 
    556513                .bind('click.' + ns, function (e) { 
    557514                    e.preventDefault(); 
    558                     filesList.find('.delete button').click(); 
     515                    filesList.find('.delete input:checked') 
     516                        .siblings('button').click(); 
     517                    fileUploadButtonBar.find('.toggle') 
     518                        .prop('checked', false); 
    559519                }); 
    560         }, 
    561          
    562         _destroyFileUploadButtonBar: function () { 
    563             this.element.find('.fileupload-buttonbar') 
    564                 .removeClass('ui-widget-header ui-corner-top'); 
    565             this.element.find('.fileinput-button').each(function () { 
    566                 var fileInput = $(this).find('input:file').detach(); 
    567                 $(this).button('destroy') 
    568                     .append(fileInput); 
    569             }); 
     520            fileUploadButtonBar.find('.toggle') 
     521                .bind('change.' + ns, function (e) { 
     522                    filesList.find('.delete input').prop( 
     523                        'checked', 
     524                        $(this).is(':checked') 
     525                    ); 
     526                }); 
     527        }, 
     528 
     529        _destroyButtonBarEventHandlers: function () { 
    570530            this.element.find('.fileupload-buttonbar button') 
    571                 .unbind('click.' + this.options.namespace) 
    572                 .button('destroy'); 
     531                .unbind('click.' + this.options.namespace); 
     532            this.element.find('.fileupload-buttonbar .toggle') 
     533                .unbind('change.' + this.options.namespace); 
     534        }, 
     535 
     536        _initEventHandlers: function () { 
     537            parentWidget.prototype._initEventHandlers.call(this); 
     538            var eventData = {fileupload: this}; 
     539            this.options.filesContainer 
     540                .delegate( 
     541                    '.start button', 
     542                    'click.' + this.options.namespace, 
     543                    eventData, 
     544                    this._startHandler 
     545                ) 
     546                .delegate( 
     547                    '.cancel button', 
     548                    'click.' + this.options.namespace, 
     549                    eventData, 
     550                    this._cancelHandler 
     551                ) 
     552                .delegate( 
     553                    '.delete button', 
     554                    'click.' + this.options.namespace, 
     555                    eventData, 
     556                    this._deleteHandler 
     557                ); 
     558            this._initButtonBarEventHandlers(); 
     559        }, 
     560 
     561        _destroyEventHandlers: function () { 
     562            var options = this.options; 
     563            this._destroyButtonBarEventHandlers(); 
     564            options.filesContainer 
     565                .undelegate('.start button', 'click.' + options.namespace) 
     566                .undelegate('.cancel button', 'click.' + options.namespace) 
     567                .undelegate('.delete button', 'click.' + options.namespace); 
     568            parentWidget.prototype._destroyEventHandlers.call(this); 
    573569        }, 
    574570 
    575571        _enableFileInputButton: function () { 
    576             this.element.find('.fileinput-button input:file:disabled') 
    577                 .each(function () { 
    578                     var fileInput = $(this), 
    579                         button = fileInput.parent(); 
    580                     fileInput.detach().prop('disabled', false); 
    581                     button.button('enable').append(fileInput); 
    582                 }); 
     572            this.element.find('.fileinput-button input') 
     573                .prop('disabled', false) 
     574                .parent().removeClass('disabled'); 
    583575        }, 
    584576 
    585577        _disableFileInputButton: function () { 
    586             this.element.find('.fileinput-button input:file:enabled') 
    587                 .each(function () { 
    588                     var fileInput = $(this), 
    589                         button = fileInput.parent(); 
    590                     fileInput.detach().prop('disabled', true); 
    591                     button.button('disable').append(fileInput); 
    592                 }); 
     578            this.element.find('.fileinput-button input') 
     579                .prop('disabled', true) 
     580                .parent().addClass('disabled'); 
    593581        }, 
    594582 
    595583        _initTemplates: function () { 
    596             // Handle cases where the templates are defined 
    597             // after the widget library has been included: 
    598             if (this.options.uploadTemplate instanceof $ && 
    599                     !this.options.uploadTemplate.length) { 
    600                 this.options.uploadTemplate = $( 
    601                     this.options.uploadTemplate.selector 
    602                 ); 
    603             } 
    604             if (this.options.downloadTemplate instanceof $ && 
    605                     !this.options.downloadTemplate.length) { 
    606                 this.options.downloadTemplate = $( 
    607                     this.options.downloadTemplate.selector 
    608                 ); 
    609             } 
     584            var options = this.options; 
     585            options.templatesContainer = document.createElement( 
     586                options.filesContainer.prop('nodeName') 
     587            ); 
     588            if (tmpl) { 
     589                if (options.uploadTemplateId) { 
     590                    options.uploadTemplate = tmpl(options.uploadTemplateId); 
     591                } 
     592                if (options.downloadTemplateId) { 
     593                    options.downloadTemplate = tmpl(options.downloadTemplateId); 
     594                } 
     595            } 
     596        }, 
     597 
     598        _initFilesContainer: function () { 
     599            var options = this.options; 
     600            if (options.filesContainer === undefined) { 
     601                options.filesContainer = this.element.find('.files'); 
     602            } else if (!(options.filesContainer instanceof $)) { 
     603                options.filesContainer = $(options.filesContainer); 
     604            } 
     605        }, 
     606 
     607        _initSpecialOptions: function () { 
     608            parentWidget.prototype._initSpecialOptions.call(this); 
     609            this._initFilesContainer(); 
     610            this._initTemplates(); 
    610611        }, 
    611612 
    612613        _create: function () { 
    613             $.blueimp.fileupload.prototype._create.call(this); 
    614             this._initTemplates(); 
    615             this.element 
    616                 .addClass('ui-widget'); 
    617             this._initFileUploadButtonBar(); 
    618             this.element.find('.fileupload-content') 
    619                 .addClass('ui-widget-content ui-corner-bottom'); 
    620             this.element.find('.fileupload-progressbar') 
    621                 .hide().progressbar(); 
    622         }, 
    623          
    624         destroy: function () { 
    625             this.element.find('.fileupload-progressbar') 
    626                 .progressbar('destroy'); 
    627             this.element.find('.fileupload-content') 
    628                 .removeClass('ui-widget-content ui-corner-bottom'); 
    629             this._destroyFileUploadButtonBar(); 
    630             this.element.removeClass('ui-widget'); 
    631             $.blueimp.fileupload.prototype.destroy.call(this); 
    632         }, 
    633          
     614            parentWidget.prototype._create.call(this); 
     615            this._refreshOptionsList.push( 
     616                'filesContainer', 
     617                'uploadTemplateId', 
     618                'downloadTemplateId' 
     619            ); 
     620            if (!$.blueimpFP) { 
     621                this._processingQueue = $.Deferred().resolveWith(this).promise(); 
     622                this.process = function () { 
     623                    return this._processingQueue; 
     624                }; 
     625            } 
     626        }, 
     627 
    634628        enable: function () { 
    635             $.blueimp.fileupload.prototype.enable.call(this); 
    636             this.element.find(':ui-button').not('.fileinput-button') 
    637                 .button('enable'); 
     629            parentWidget.prototype.enable.call(this); 
     630            this.element.find('input, button').prop('disabled', false); 
    638631            this._enableFileInputButton(); 
    639632        }, 
    640          
     633 
    641634        disable: function () { 
    642             this.element.find(':ui-button').not('.fileinput-button') 
    643                 .button('disable'); 
     635            this.element.find('input, button').prop('disabled', true); 
    644636            this._disableFileInputButton(); 
    645             $.blueimp.fileupload.prototype.disable.call(this); 
     637            parentWidget.prototype.disable.call(this); 
    646638        } 
    647639 
    648640    }); 
    649641 
    650 }(jQuery)); 
     642})); 
  • trunk/prototype/plugins/fileupload/jquery.fileupload.js

    r5341 r6107  
    11/* 
    2  * jQuery File Upload Plugin 5.2 
     2 * jQuery File Upload Plugin 5.10.1 
    33 * https://github.com/blueimp/jQuery-File-Upload 
    44 * 
     
    77 * 
    88 * Licensed under the MIT license: 
    9  * http://creativecommons.org/licenses/MIT/ 
     9 * http://www.opensource.org/licenses/MIT 
    1010 */ 
    1111 
    1212/*jslint nomen: true, unparam: true, regexp: true */ 
    13 /*global document, XMLHttpRequestUpload, Blob, File, FormData, location, jQuery */ 
    14  
    15 (function ($) { 
     13/*global define, window, document, Blob, FormData, location */ 
     14 
     15(function (factory) { 
    1616    'use strict'; 
    17  
    18     // The fileupload widget listens for change events on file input fields 
    19     // defined via fileInput setting and drop events of the given dropZone. 
     17    if (typeof define === 'function' && define.amd) { 
     18        // Register as an anonymous AMD module: 
     19        define([ 
     20            'jquery', 
     21            'jquery.ui.widget' 
     22        ], factory); 
     23    } else { 
     24        // Browser globals: 
     25        factory(window.jQuery); 
     26    } 
     27}(function ($) { 
     28    'use strict'; 
     29 
     30    // The FileReader API is not actually used, but works as feature detection, 
     31    // as e.g. Safari supports XHR file uploads via the FormData API, 
     32    // but not non-multipart XHR file uploads: 
     33    $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader); 
     34    $.support.xhrFormDataFileUpload = !!window.FormData; 
     35 
     36    // The fileupload widget listens for change events on file input fields defined 
     37    // via fileInput setting and paste or drop events of the given dropZone. 
    2038    // In addition to the default jQuery Widget methods, the fileupload widget 
    21     // exposes the "add" and "send" methods, to add or directly send files 
    22     // using the fileupload API. 
    23     // By default, files added via file input selection, drag & drop or 
     39    // exposes the "add" and "send" methods, to add or directly send files using 
     40    // the fileupload API. 
     41    // By default, files added via file input selection, paste, drag & drop or 
    2442    // "add" method are uploaded immediately, but it is possible to override 
    2543    // the "add" callback option to queue file uploads. 
    2644    $.widget('blueimp.fileupload', { 
    27          
     45 
    2846        options: { 
    2947            // The namespace used for event handler binding on the dropZone and 
     
    4664            // The parameter name for the file form data (the request argument name). 
    4765            // If undefined or empty, the name property of the file input field is 
    48             // used, or "files[]" if the file input name property is also empty: 
     66            // used, or "files[]" if the file input name property is also empty, 
     67            // can be a string or an array of strings: 
    4968            paramName: undefined, 
    5069            // By default, each file of a selection is uploaded using an individual 
     
    6382            // Set the following option to true to force iframe transport uploads: 
    6483            forceIframeTransport: false, 
     84            // Set the following option to the location of a redirect url on the 
     85            // origin server, for cross-domain iframe transport uploads: 
     86            redirect: undefined, 
     87            // The parameter name for the redirect url, sent as part of the form 
     88            // data and set to 'redirect' if this option is empty: 
     89            redirectParamName: undefined, 
     90            // Set the following option to the location of a postMessage window, 
     91            // to enable postMessage transport uploads: 
     92            postMessage: undefined, 
    6593            // By default, XHR file uploads are sent as multipart/form-data. 
    6694            // The iframe transport is always using multipart/form-data. 
     
    82110            // prevent recalculating the global progress data: 
    83111            recalculateProgress: true, 
    84              
     112 
    85113            // Additional form data to be sent along with the file uploads can be set 
    86114            // using this option, which accepts an array of objects with name and 
     
    91119                return form.serializeArray(); 
    92120            }, 
    93              
     121 
    94122            // The add callback is invoked as soon as files are added to the fileupload 
    95             // widget (via file input selection, drag & drop or add API call). 
     123            // widget (via file input selection, drag & drop, paste or add API call). 
    96124            // If the singleFileUploads option is enabled, this callback will be 
    97125            // called once for each file in the selection for XHR file uplaods, else 
     
    108136                data.submit(); 
    109137            }, 
    110              
     138 
    111139            // Other callbacks: 
     140            // Callback for the submit event of each file upload: 
     141            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func); 
    112142            // Callback for the start of each file upload request: 
    113143            // send: function (e, data) {}, // .bind('fileuploadsend', func); 
     
    128158            // Callback for change events of the fileInput collection: 
    129159            // change: function (e, data) {}, // .bind('fileuploadchange', func); 
     160            // Callback for paste events to the dropZone collection: 
     161            // paste: function (e, data) {}, // .bind('fileuploadpaste', func); 
    130162            // Callback for drop events of the dropZone collection: 
    131163            // drop: function (e, data) {}, // .bind('fileuploaddrop', func); 
    132164            // Callback for dragover events of the dropZone collection: 
    133165            // dragover: function (e) {}, // .bind('fileuploaddragover', func); 
    134              
     166 
    135167            // The plugin options are used as settings object for the ajax calls. 
    136168            // The following are jQuery ajax settings required for the file uploads: 
     
    139171            cache: false 
    140172        }, 
    141          
     173 
    142174        // A list of options that require a refresh after assigning a new value: 
    143         _refreshOptionsList: ['namespace', 'dropZone', 'fileInput'], 
     175        _refreshOptionsList: [ 
     176            'namespace', 
     177            'dropZone', 
     178            'fileInput', 
     179            'multipart', 
     180            'forceIframeTransport' 
     181        ], 
    144182 
    145183        _isXHRUpload: function (options) { 
    146             var undef = 'undefined'; 
    147184            return !options.forceIframeTransport && 
    148                 typeof XMLHttpRequestUpload !== undef && typeof File !== undef && 
    149                 (!options.multipart || typeof FormData !== undef); 
     185                ((!options.multipart && $.support.xhrFileUpload) || 
     186                $.support.xhrFormDataFileUpload); 
    150187        }, 
    151188 
     
    204241            // Accesss to the native XHR object is required to add event listeners 
    205242            // for the upload progress event: 
    206             if (xhr.upload && xhr.upload.addEventListener) { 
    207                 xhr.upload.addEventListener('progress', function (e) { 
     243            if (xhr.upload) { 
     244                $(xhr.upload).bind('progress', function (e) { 
     245                    var oe = e.originalEvent; 
     246                    // Make sure the progress event properties get copied over: 
     247                    e.lengthComputable = oe.lengthComputable; 
     248                    e.loaded = oe.loaded; 
     249                    e.total = oe.total; 
    208250                    that._onProgress(e, options); 
    209                 }, false); 
     251                }); 
    210252                options.xhr = function () { 
    211253                    return xhr; 
     
    216258        _initXHRData: function (options) { 
    217259            var formData, 
    218                 file = options.files[0]; 
    219             if (!options.multipart || options.blob) { 
     260                file = options.files[0], 
     261                // Ignore non-multipart setting if not supported: 
     262                multipart = options.multipart || !$.support.xhrFileUpload, 
     263                paramName = options.paramName[0]; 
     264            if (!multipart || options.blob) { 
    220265                // For non-multipart uploads and chunked uploads, 
    221266                // file meta data is not part of the request body, 
     
    233278                    options.contentType = file.type; 
    234279                    options.data = file; 
    235                 } else if (!options.multipart) { 
     280                } else if (!multipart) { 
    236281                    // Chunked non-multipart upload: 
    237282                    options.contentType = 'application/octet-stream'; 
     
    239284                } 
    240285            } 
    241             if (options.multipart && typeof FormData !== 'undefined') { 
    242                 if (options.formData instanceof FormData) { 
    243                     formData = options.formData; 
     286            if (multipart && $.support.xhrFormDataFileUpload) { 
     287                if (options.postMessage) { 
     288                    // window.postMessage does not allow sending FormData 
     289                    // objects, so we just add the File/Blob objects to 
     290                    // the formData array and let the postMessage window 
     291                    // create the FormData object out of this array: 
     292                    formData = this._getFormData(options); 
     293                    if (options.blob) { 
     294                        formData.push({ 
     295                            name: paramName, 
     296                            value: options.blob 
     297                        }); 
     298                    } else { 
     299                        $.each(options.files, function (index, file) { 
     300                            formData.push({ 
     301                                name: options.paramName[index] || paramName, 
     302                                value: file 
     303                            }); 
     304                        }); 
     305                    } 
    244306                } else { 
    245                     formData = new FormData(); 
    246                     $.each(this._getFormData(options), function (index, field) { 
    247                         formData.append(field.name, field.value); 
    248                     }); 
    249                 } 
    250                 if (options.blob) { 
    251                     formData.append(options.paramName, options.blob); 
    252                 } else { 
    253                     $.each(options.files, function (index, file) { 
    254                         // File objects are also Blob instances. 
    255                         // This check allows the tests to run with 
    256                         // dummy objects: 
    257                         if (file instanceof Blob) { 
    258                             formData.append(options.paramName, file); 
    259                         } 
    260                     }); 
     307                    if (options.formData instanceof FormData) { 
     308                        formData = options.formData; 
     309                    } else { 
     310                        formData = new FormData(); 
     311                        $.each(this._getFormData(options), function (index, field) { 
     312                            formData.append(field.name, field.value); 
     313                        }); 
     314                    } 
     315                    if (options.blob) { 
     316                        formData.append(paramName, options.blob, file.name); 
     317                    } else { 
     318                        $.each(options.files, function (index, file) { 
     319                            // File objects are also Blob instances. 
     320                            // This check allows the tests to run with 
     321                            // dummy objects: 
     322                            if (file instanceof Blob) { 
     323                                formData.append( 
     324                                    options.paramName[index] || paramName, 
     325                                    file, 
     326                                    file.name 
     327                                ); 
     328                            } 
     329                        }); 
     330                    } 
    261331                } 
    262332                options.data = formData; 
     
    265335            options.blob = null; 
    266336        }, 
    267          
     337 
    268338        _initIframeSettings: function (options) { 
    269339            // Setting the dataType to iframe enables the iframe transport: 
     
    271341            // The iframe transport accepts a serialized array as form data: 
    272342            options.formData = this._getFormData(options); 
    273         }, 
    274          
     343            // Add redirect url to form data on cross-domain uploads: 
     344            if (options.redirect && $('<a></a>').prop('href', options.url) 
     345                    .prop('host') !== location.host) { 
     346                options.formData.push({ 
     347                    name: options.redirectParamName || 'redirect', 
     348                    value: options.redirect 
     349                }); 
     350            } 
     351        }, 
     352 
    275353        _initDataSettings: function (options) { 
    276354            if (this._isXHRUpload(options)) { 
     
    281359                    this._initProgressListener(options); 
    282360                } 
     361                if (options.postMessage) { 
     362                    // Setting the dataType to postmessage enables the 
     363                    // postMessage transport: 
     364                    options.dataType = 'postmessage ' + (options.dataType || ''); 
     365                } 
    283366            } else { 
    284                 this._initIframeSettings(options); 
    285             } 
    286         }, 
    287          
     367                this._initIframeSettings(options, 'iframe'); 
     368            } 
     369        }, 
     370 
     371        _getParamName: function (options) { 
     372            var fileInput = $(options.fileInput), 
     373                paramName = options.paramName; 
     374            if (!paramName) { 
     375                paramName = []; 
     376                fileInput.each(function () { 
     377                    var input = $(this), 
     378                        name = input.prop('name') || 'files[]', 
     379                        i = (input.prop('files') || [1]).length; 
     380                    while (i) { 
     381                        paramName.push(name); 
     382                        i -= 1; 
     383                    } 
     384                }); 
     385                if (!paramName.length) { 
     386                    paramName = [fileInput.prop('name') || 'files[]']; 
     387                } 
     388            } else if (!$.isArray(paramName)) { 
     389                paramName = [paramName]; 
     390            } 
     391            return paramName; 
     392        }, 
     393 
    288394        _initFormSettings: function (options) { 
    289395            // Retrieve missing options from the input field and the 
     
    292398                options.form = $(options.fileInput.prop('form')); 
    293399            } 
    294             if (!options.paramName) { 
    295                 options.paramName = options.fileInput.prop('name') || 
    296                     'files[]'; 
    297             } 
     400            options.paramName = this._getParamName(options); 
    298401            if (!options.url) { 
    299402                options.url = options.form.prop('action') || location.href; 
     
    306409            } 
    307410        }, 
    308          
     411 
    309412        _getAJAXSettings: function (data) { 
    310413            var options = $.extend({}, this.options, data); 
     
    365468            if (ub >= fs) { 
    366469                file.error = 'uploadedBytes'; 
    367                 return this._getXHRPromise(false); 
     470                return this._getXHRPromise( 
     471                    false, 
     472                    options.context, 
     473                    [null, 'error', file.error] 
     474                ); 
    368475            } 
    369476            // n is the number of blobs to upload, 
     
    373480            upload = function (i) { 
    374481                if (!i) { 
    375                     return that._getXHRPromise(true); 
     482                    return that._getXHRPromise(true, options.context); 
    376483                } 
    377484                // Upload the blobs in sequential order: 
     
    402509                                }), o); 
    403510                            } 
    404                             options.uploadedBytes = o.uploadedBytes 
    405                                 += o.chunkSize; 
     511                            options.uploadedBytes = o.uploadedBytes += 
     512                                o.chunkSize; 
    406513                        }); 
    407514                    return jqXHR; 
     
    459566        }, 
    460567 
    461         _onAlways: function (result, textStatus, jqXHR, errorThrown, options) { 
     568        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { 
    462569            this._active -= 1; 
    463             options.result = result; 
    464570            options.textStatus = textStatus; 
    465             options.jqXHR = jqXHR; 
    466             options.errorThrown = errorThrown; 
     571            if (jqXHRorError && jqXHRorError.always) { 
     572                options.jqXHR = jqXHRorError; 
     573                options.result = jqXHRorResult; 
     574            } else { 
     575                options.jqXHR = jqXHRorResult; 
     576                options.errorThrown = jqXHRorError; 
     577            } 
    467578            this._trigger('always', null, options); 
    468579            if (this._active === 0) { 
     
    492603                    }).fail(function (jqXHR, textStatus, errorThrown) { 
    493604                        that._onFail(jqXHR, textStatus, errorThrown, options); 
    494                     }).always(function (a1, a2, a3) { 
     605                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) { 
    495606                        that._sending -= 1; 
    496                         if (a3 && a3.done) { 
    497                             that._onAlways(a1, a2, a3, undefined, options); 
    498                         } else { 
    499                             that._onAlways(undefined, a2, a1, a3, options); 
    500                         } 
     607                        that._onAlways( 
     608                            jqXHRorResult, 
     609                            textStatus, 
     610                            jqXHRorError, 
     611                            options 
     612                        ); 
    501613                        if (options.limitConcurrentUploads && 
    502614                                options.limitConcurrentUploads > that._sending) { 
     
    543655            return send(); 
    544656        }, 
    545          
     657 
    546658        _onAdd: function (e, data) { 
    547659            var that = this, 
    548660                result = true, 
    549661                options = $.extend({}, this.options, data), 
    550                 fileSet = data.files, 
    551662                limit = options.limitMultiFileUploads, 
     663                paramName = this._getParamName(options), 
     664                paramNameSet, 
     665                paramNameSlice, 
     666                fileSet, 
    552667                i; 
    553668            if (!(options.singleFileUploads || limit) || 
    554669                    !this._isXHRUpload(options)) { 
    555                 fileSet = [fileSet]; 
     670                fileSet = [data.files]; 
     671                paramNameSet = [paramName]; 
    556672            } else if (!options.singleFileUploads && limit) { 
    557673                fileSet = []; 
     674                paramNameSet = []; 
    558675                for (i = 0; i < data.files.length; i += limit) { 
    559676                    fileSet.push(data.files.slice(i, i + limit)); 
    560                 } 
    561             } 
    562             $.each(fileSet, function (index, file) { 
    563                 var files = $.isArray(file) ? file : [file], 
    564                     newData = $.extend({}, data, {files: files}); 
     677                    paramNameSlice = paramName.slice(i, i + limit); 
     678                    if (!paramNameSlice.length) { 
     679                        paramNameSlice = paramName; 
     680                    } 
     681                    paramNameSet.push(paramNameSlice); 
     682                } 
     683            } else { 
     684                paramNameSet = paramName; 
     685            } 
     686            data.originalFiles = data.files; 
     687            $.each(fileSet || data.files, function (index, element) { 
     688                var newData = $.extend({}, data); 
     689                newData.files = fileSet ? element : [element]; 
     690                newData.paramName = paramNameSet[index]; 
    565691                newData.submit = function () { 
    566                     return that._onSend(e, newData); 
     692                    newData.jqXHR = this.jqXHR = 
     693                        (that._trigger('submit', e, this) !== false) && 
     694                        that._onSend(e, this); 
     695                    return this.jqXHR; 
    567696                }; 
    568697                return (result = that._trigger('add', e, newData)); 
     
    570699            return result; 
    571700        }, 
    572          
     701 
    573702        // File Normalization for Gecko 1.9.1 (Firefox 3.5) support: 
    574703        _normalizeFile: function (index, file) { 
     
    585714            // without loosing the file input value: 
    586715            input.after(inputClone).detach(); 
     716            // Avoid memory leaks with the detached file input: 
     717            $.cleanData(input.unbind('remove')); 
    587718            // Replace the original file input element in the fileInput 
    588719            // collection with the clone, which has been copied including 
     
    594725                return el; 
    595726            }); 
    596         }, 
    597          
     727            // If the widget has been initialized on the file input itself, 
     728            // override this.element with the file input clone: 
     729            if (input[0] === this.element[0]) { 
     730                this.element = inputClone; 
     731            } 
     732        }, 
     733 
    598734        _onChange: function (e) { 
    599735            var that = e.data.fileupload, 
     
    609745                data.files = [{name: e.target.value.replace(/^.*\\/, '')}]; 
    610746            } 
    611             // Store the form reference as jQuery data for other event handlers, 
    612             // as the form property is not available after replacing the file input:  
    613             if (data.form.length) { 
    614                 data.fileInput.data('blueimp.fileupload.form', data.form); 
    615             } else { 
    616                 data.form = data.fileInput.data('blueimp.fileupload.form'); 
    617             } 
    618747            if (that.options.replaceFileInput) { 
    619748                that._replaceFileInput(data.fileInput); 
     
    624753            } 
    625754        }, 
    626          
     755 
     756        _onPaste: function (e) { 
     757            var that = e.data.fileupload, 
     758                cbd = e.originalEvent.clipboardData, 
     759                items = (cbd && cbd.items) || [], 
     760                data = {files: []}; 
     761            $.each(items, function (index, item) { 
     762                var file = item.getAsFile && item.getAsFile(); 
     763                if (file) { 
     764                    data.files.push(file); 
     765                } 
     766            }); 
     767            if (that._trigger('paste', e, data) === false || 
     768                    that._onAdd(e, data) === false) { 
     769                return false; 
     770            } 
     771        }, 
     772 
    627773        _onDrop: function (e) { 
    628774            var that = e.data.fileupload, 
     
    640786            e.preventDefault(); 
    641787        }, 
    642          
     788 
    643789        _onDragOver: function (e) { 
    644790            var that = e.data.fileupload, 
     
    652798            e.preventDefault(); 
    653799        }, 
    654          
     800 
    655801        _initEventHandlers: function () { 
    656             var ns = this.options.namespace || this.name; 
    657             this.options.dropZone 
    658                 .bind('dragover.' + ns, {fileupload: this}, this._onDragOver) 
    659                 .bind('drop.' + ns, {fileupload: this}, this._onDrop); 
     802            var ns = this.options.namespace; 
     803            if (this._isXHRUpload(this.options)) { 
     804                this.options.dropZone 
     805                    .bind('dragover.' + ns, {fileupload: this}, this._onDragOver) 
     806                    .bind('drop.' + ns, {fileupload: this}, this._onDrop) 
     807                    .bind('paste.' + ns, {fileupload: this}, this._onPaste); 
     808            } 
    660809            this.options.fileInput 
    661810                .bind('change.' + ns, {fileupload: this}, this._onChange); 
     
    663812 
    664813        _destroyEventHandlers: function () { 
    665             var ns = this.options.namespace || this.name; 
     814            var ns = this.options.namespace; 
    666815            this.options.dropZone 
    667816                .unbind('dragover.' + ns, this._onDragOver) 
    668                 .unbind('drop.' + ns, this._onDrop); 
     817                .unbind('drop.' + ns, this._onDrop) 
     818                .unbind('paste.' + ns, this._onPaste); 
    669819            this.options.fileInput 
    670820                .unbind('change.' + ns, this._onChange); 
    671821        }, 
    672          
    673         _beforeSetOption: function (key, value) { 
    674             this._destroyEventHandlers(); 
    675         }, 
    676          
    677         _afterSetOption: function (key, value) { 
    678             var options = this.options; 
    679             if (!options.fileInput) { 
    680                 options.fileInput = $(); 
    681             } 
    682             if (!options.dropZone) { 
    683                 options.dropZone = $(); 
    684             } 
    685             this._initEventHandlers(); 
    686         }, 
    687          
     822 
    688823        _setOption: function (key, value) { 
    689824            var refresh = $.inArray(key, this._refreshOptionsList) !== -1; 
    690825            if (refresh) { 
    691                 this._beforeSetOption(key, value); 
     826                this._destroyEventHandlers(); 
    692827            } 
    693828            $.Widget.prototype._setOption.call(this, key, value); 
    694829            if (refresh) { 
    695                 this._afterSetOption(key, value); 
    696             } 
    697         }, 
    698  
    699         _create: function () { 
     830                this._initSpecialOptions(); 
     831                this._initEventHandlers(); 
     832            } 
     833        }, 
     834 
     835        _initSpecialOptions: function () { 
    700836            var options = this.options; 
    701837            if (options.fileInput === undefined) { 
    702838                options.fileInput = this.element.is('input:file') ? 
    703                     this.element : this.element.find('input:file'); 
    704             } else if (!options.fileInput) { 
    705                 options.fileInput = $(); 
    706             } 
    707             if (!options.dropZone) { 
    708                 options.dropZone = $(); 
    709             } 
     839                        this.element : this.element.find('input:file'); 
     840            } else if (!(options.fileInput instanceof $)) { 
     841                options.fileInput = $(options.fileInput); 
     842            } 
     843            if (!(options.dropZone instanceof $)) { 
     844                options.dropZone = $(options.dropZone); 
     845            } 
     846        }, 
     847 
     848        _create: function () { 
     849            var options = this.options; 
     850            // Initialize options set via HTML5 data-attributes: 
     851            $.extend(options, $(this.element[0].cloneNode(false)).data()); 
     852            options.namespace = options.namespace || this.widgetName; 
     853            this._initSpecialOptions(); 
    710854            this._slots = []; 
    711855            this._sequence = this._getXHRPromise(true); 
     
    713857            this._initEventHandlers(); 
    714858        }, 
    715          
     859 
    716860        destroy: function () { 
    717861            this._destroyEventHandlers(); 
     
    723867            this._initEventHandlers(); 
    724868        }, 
    725          
     869 
    726870        disable: function () { 
    727871            this._destroyEventHandlers(); 
     
    740884            this._onAdd(null, data); 
    741885        }, 
    742          
     886 
    743887        // This method is exposed to the widget API and allows sending files 
    744888        // using the fileupload API. The data parameter accepts an object which 
     
    755899            return this._getXHRPromise(false, data && data.context); 
    756900        } 
    757          
     901 
    758902    }); 
    759      
    760 }(jQuery)); 
     903 
     904})); 
  • trunk/prototype/plugins/fileupload/jquery.iframe-transport.js

    r5341 r6107  
    11/* 
    2  * jQuery Iframe Transport Plugin 1.2.2 
     2 * jQuery Iframe Transport Plugin 1.4 
    33 * https://github.com/blueimp/jQuery-File-Upload 
    44 * 
     
    77 * 
    88 * Licensed under the MIT license: 
    9  * http://creativecommons.org/licenses/MIT/ 
     9 * http://www.opensource.org/licenses/MIT 
    1010 */ 
    1111 
    12 /*jslint unparam: true */ 
    13 /*global jQuery */ 
     12/*jslint unparam: true, nomen: true */ 
     13/*global define, window, document */ 
    1414 
    15 (function ($) { 
     15(function (factory) { 
     16    'use strict'; 
     17    if (typeof define === 'function' && define.amd) { 
     18        // Register as an anonymous AMD module: 
     19        define(['jquery'], factory); 
     20    } else { 
     21        // Browser globals: 
     22        factory(window.jQuery); 
     23    } 
     24}(function ($) { 
    1625    'use strict'; 
    1726 
     
    2231    // options.fileInput: a jQuery collection of file input fields 
    2332    // options.paramName: the parameter name for the file form data, 
    24     //  overrides the name property of the file input field(s) 
     33    //  overrides the name property of the file input field(s), 
     34    //  can be a string or an array of strings. 
    2535    // options.formData: an array of objects with name and value properties, 
    2636    //  equivalent to the return data of .serializeArray(), e.g.: 
    27     //  [{name: a, value: 1}, {name: b, value: 2}] 
    28     $.ajaxTransport('iframe', function (options, originalOptions, jqXHR) { 
    29         if (options.type === 'POST' || options.type === 'GET') { 
     37    //  [{name: 'a', value: 1}, {name: 'b', value: 2}] 
     38    $.ajaxTransport('iframe', function (options) { 
     39        if (options.async && (options.type === 'POST' || options.type === 'GET')) { 
    3040            var form, 
    3141                iframe; 
    3242            return { 
    33                 send: function (headers, completeCallback) { 
     43                send: function (_, completeCallback) { 
    3444                    form = $('<form style="display:none;"></form>'); 
    3545                    // javascript:false as initial iframe src 
     
    4252                            (counter += 1) + '"></iframe>' 
    4353                    ).bind('load', function () { 
    44                         var fileInputClones; 
     54                        var fileInputClones, 
     55                            paramNames = $.isArray(options.paramName) ? 
     56                                    options.paramName : [options.paramName]; 
    4557                        iframe 
    4658                            .unbind('load') 
     
    93105                            }); 
    94106                            if (options.paramName) { 
    95                                 options.fileInput.each(function () { 
    96                                     $(this).prop('name', options.paramName); 
     107                                options.fileInput.each(function (index) { 
     108                                    $(this).prop( 
     109                                        'name', 
     110                                        paramNames[index] || options.paramName 
     111                                    ); 
    97112                                }); 
    98113                            } 
     
    116131                        } 
    117132                    }); 
    118                     form.append(iframe).appendTo('body'); 
     133                    form.append(iframe).appendTo(document.body); 
    119134                }, 
    120135                abort: function () { 
     
    140155        converters: { 
    141156            'iframe text': function (iframe) { 
    142                 return iframe.text(); 
     157                return $(iframe[0].body).text(); 
    143158            }, 
    144159            'iframe json': function (iframe) { 
    145                 return $.parseJSON(iframe.text()); 
     160                return $.parseJSON($(iframe[0].body).text()); 
    146161            }, 
    147162            'iframe html': function (iframe) { 
    148                 return iframe.find('body').html(); 
     163                return $(iframe[0].body).html(); 
    149164            }, 
    150165            'iframe script': function (iframe) { 
    151                 return $.globalEval(iframe.text()); 
     166                return $.globalEval($(iframe[0].body).text()); 
    152167            } 
    153168        } 
    154169    }); 
    155170 
    156 }(jQuery)); 
     171})); 
Note: See TracChangeset for help on using the changeset viewer.