Changeset 6107
- Timestamp:
- 05/04/12 18:00:28 (12 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/expressoMail1_2/js/draw_api.js
r6106 r6107 1701 1701 headers_msgs.followupflagged.id = DataLayer.put('followupflagged', headers_msgs.followupflagged); 1702 1702 DataLayer.commit(false, false, function(data){ 1703 var fail = false;1703 var fail = false; 1704 1704 $.each(data, function(index, value) { 1705 fail = false; 1706 if(typeof value != 'object' || !(value['id'])){ 1705 if(typeof value != 'object'){ 1707 1706 fail = true; 1707 alert(value); 1708 1708 } 1709 1709 }); … … 1720 1720 $('#td_message_followup_' + messageClickedId + ', ' + 1721 1721 '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.");1723 1722 } 1724 1723 }); … … 3017 3016 //TODO Mudar quando API abstrair atualizações no cache 3018 3017 DataLayer.remove('labeled', false); 3019 //DataLayer.get('labeled');3018 DataLayer.get('labeled'); 3020 3019 var labels = DataLayer.get("labeled", {filter: [ 3021 3020 'AND', … … 3044 3043 var id_labeled = $(event.target).attr("id"); 3045 3044 //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'); 3048 3047 DataLayer.remove('labeled', id_labeled); 3049 3048 DataLayer.commit(false, false, function(){ … … 3678 3677 var fileUploadMSG = $('#fileupload_msg'+ID); 3679 3678 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, 3682 3683 type: 'post', 3683 3684 dataType : 'json', 3684 3685 url: "../prototype/post.php", 3685 forceIframeTransport: true, 3686 forceIframeTransport: false, 3687 dropZone : fileUploadMSG, 3686 3688 formData: function(form) { 3689 $.each(this.files, function(index, value){ 3690 3691 }); 3687 3692 return [ 3688 3693 { … … 3699 3704 } 3700 3705 ]; 3701 }, 3706 }, 3702 3707 add: function (e, data) { 3703 3704 3708 if(!maxAttachmentSize || data.files[0].size < maxAttachmentSize || is_ie) { 3705 3709 setTimeout(function() { 3706 3710 $('#attDisposition'+ID).val('attachment'); 3707 3711 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"); 3710 3715 } 3711 if(!data.form)3712 data['form'] = fileUploadMSG.parents("form:first");3713 3716 data.submit(); 3714 3717 }, 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'); 3737 3751 }); 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 else3744 fileUploadMSG.find(' .fileinput-button.new').removeClass('new');3745 3752 }, 3746 3753 done: function(e, data){ … … 3764 3771 fileUploadMSG.find(' .in-progress:first').remove(); 3765 3772 } 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'); 3768 3932 3769 3933 fileUploadMSG.find("span.message-attach-link").click(function(event){ … … 3833 3997 3834 3998 }); 3999 */ 3835 4000 // style="width: 100px; height: 20px;"/ 3836 4001 //$('[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 1 1 <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 /> 19 18 </div> -
trunk/prototype/modules/mail/templates/attachment_add_itemlist.ejs
r5767 r6107 1 <li style="list-style : none;"> 1 2 <p class="input-group archive-info" style="margin: 0px 0 !important; height: 17px"> 2 3 <span title="<%=data.file.fullFileName%>" class="archive-attach name"><%=data.file.fileName%></span> 3 4 <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> 5 6 <span class="status-upload"></span> 6 7 <%if(data.file.error){%> … … 14 15 15 16 </p> 17 </li> -
trunk/prototype/modules/mail/templates/new_message.ejs
r6060 r6107 119 119 </td> 120 120 <td class="value"> 121 <div id="message-attach-dialog" title="'<%=get_lang("Select messages to attach...")%>" style="clear: both; ")> </div>121 <div id="message-attach-dialog" title="'<%=get_lang("Select messages to attach...")%>" style="clear: both; display:none;")> </div> 122 122 </td> 123 123 </tr> -
trunk/prototype/plugins/fileupload/jquery.fileupload-ui.css
r5341 r6107 1 1 @charset 'UTF-8'; 2 2 /* 3 * jQuery File Upload UI Plugin CSS 5.0.63 * jQuery File Upload UI Plugin CSS 6.3 4 4 * https://github.com/blueimp/jQuery-File-Upload 5 5 * … … 8 8 * 9 9 * Licensed under the MIT license: 10 * http:// creativecommons.org/licenses/MIT/10 * http://www.opensource.org/licenses/MIT 11 11 */ 12 12 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 { 14 20 position: absolute; 15 21 top: 0; … … 20 26 opacity: 0; 21 27 filter: alpha(opacity=0); 22 -o-transform: translate(250px, -50px) scale(1);23 28 -moz-transform: translate(-300px, 0) scale(4); 24 29 direction: ltr; 25 30 cursor: pointer; 26 31 } 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; 30 53 } 31 54 32 55 /* Fix for IE 6: */ 33 56 *html .fileinput-button { 34 padding: 2px 0; 57 line-height: 22px; 58 margin: 1px -3px 0 0; 35 59 } 36 60 37 61 /* Fix for IE 7: */ 38 62 *+html .fileinput-button { 39 padding: 2px0;63 margin: 1px 0 0 0; 40 64 } 41 65 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 } 44 84 } 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 1 1 /* 2 * jQuery File Upload User Interface Plugin 5.0.162 * jQuery File Upload User Interface Plugin 6.7 3 3 * https://github.com/blueimp/jQuery-File-Upload 4 4 * … … 7 7 * 8 8 * Licensed under the MIT license: 9 * http:// creativecommons.org/licenses/MIT/9 * http://www.opensource.org/licenses/MIT 10 10 */ 11 11 12 12 /*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) { 16 16 '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 23 41 options: { 24 42 // By default, files added to the widget are uploaded as soon … … 32 50 maxFileSize: undefined, 33 51 // The minimum allowed file size: 34 minFileSize: 1,52 minFileSize: undefined, 35 53 // The regular expression for allowed file types, matches 36 54 // against either file type or file name: … … 38 56 // The regular expression to define for which files a preview 39 57 // 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 41 61 // The maximum width of the preview images: 42 62 previewMaxWidth: 80, … … 47 67 // to always display preview images as img elements: 48 68 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, 55 79 // The expected data type of the upload response, sets the dataType 56 80 // option of the $.ajax upload requests: 57 81 dataType: 'json', 58 82 59 83 // The add callback is invoked as soon as files are added to the fileupload 60 84 // widget (via file input selection, drag & drop or add API call). 61 85 // See the basic file upload widget for more information: 62 86 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 }); 76 110 }, 77 111 // Callback for the start of each file upload request: 78 112 send: function (e, data) { 113 var that = $(this).data('fileupload'); 79 114 if (!data.isValidated) { 80 var that = $(this).data('fileupload');81 115 if (!data.isAdjusted) { 82 116 that._adjustMaxNumberOfFiles(-data.files.length); … … 91 125 // In lack of an indeterminate progress bar, we set 92 126 // 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); 98 137 }, 99 138 // Callback for successful uploads: 100 139 done: function (e, data) { 101 var that = $(this).data('fileupload'); 140 var that = $(this).data('fileupload'), 141 template, 142 preview; 102 143 if (data.context) { 103 144 data.context.each(function (index) { … … 107 148 that._adjustMaxNumberOfFiles(1); 108 149 } 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 ); 118 165 }); 119 166 } 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 ); 127 176 } 128 177 }, 129 178 // Callback for failed (abort or error) uploads: 130 179 fail: function (e, data) { 131 var that = $(this).data('fileupload'); 180 var that = $(this).data('fileupload'), 181 template; 132 182 that._adjustMaxNumberOfFiles(data.files.length); 133 183 if (data.context) { 134 184 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 } 151 211 }); 152 212 } else if (data.errorThrown !== 'abort') { 153 213 that._adjustMaxNumberOfFiles(-data.files.length); 154 214 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); 161 226 } 162 227 }, … … 164 229 progress: function (e, data) { 165 230 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) + '%' 169 234 ); 170 235 } … … 172 237 // Callback for global upload progress events: 173 238 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) + '%' 177 242 ); 178 243 }, 179 244 // 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 ); 183 252 }, 184 253 // 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 ); 187 262 }, 188 263 // Callback for file deletion: … … 190 265 var that = $(this).data('fileupload'); 191 266 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 () { 202 272 $(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 } 218 275 ); 219 if (scale >= 1) {220 scale = Math.max(221 (options.minWidth || img.width) / img.width,222 (options.minHeight || img.height) / img.height223 );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 canvas270 // 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 }290 276 } 291 277 }, … … 296 282 var link = $(this), 297 283 url = link.prop('href'), 298 name = decodeURIComponent(url.split('/').pop()) 299 .replace(/:/g, '-'), 284 name = link.prop('download'), 300 285 type = 'application/octet-stream'; 301 286 link.bind('dragstart', function (e) { … … 320 305 }, 321 306 322 _formatFileSize: function ( file) {323 if (typeof file.size!== 'number') {307 _formatFileSize: function (bytes) { 308 if (typeof bytes !== 'number') { 324 309 return ''; 325 310 } 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'; 333 318 }, 334 319 … … 373 358 }, 374 359 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 _render Upload: 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) { 391 376 var that = this, 392 377 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); 428 392 } 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 } 430 420 }); 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( 442 433 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 463 438 _startHandler: function (e) { 464 439 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 473 448 _cancelHandler: function (e) { 474 449 e.preventDefault(); 475 var t mpl= $(this).closest('.template-upload'),476 data = t mpl.data('data') || {};450 var template = $(this).closest('.template-upload'), 451 data = template.data('data') || {}; 477 452 if (!data.jqXHR) { 478 453 data.errorThrown = 'abort'; … … 482 457 } 483 458 }, 484 459 485 460 _deleteHandler: function (e) { 486 461 e.preventDefault(); … … 489 464 context: button.closest('.template-download'), 490 465 url: button.attr('data-url'), 491 type: button.attr('data-type') ,466 type: button.attr('data-type') || 'DELETE', 492 467 dataType: e.data.fileupload.options.dataType 493 468 }); 494 469 }, 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 () { 532 499 var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'), 533 filesList = this. element.find('.files'),500 filesList = this.options.filesContainer, 534 501 ns = this.options.namespace; 535 fileUploadButtonBar536 .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 });542 502 fileUploadButtonBar.find('.start') 543 .button({icons: {primary: 'ui-icon-circle-arrow-e'}})544 503 .bind('click.' + ns, function (e) { 545 504 e.preventDefault(); … … 547 506 }); 548 507 fileUploadButtonBar.find('.cancel') 549 .button({icons: {primary: 'ui-icon-cancel'}})550 508 .bind('click.' + ns, function (e) { 551 509 e.preventDefault(); … … 553 511 }); 554 512 fileUploadButtonBar.find('.delete') 555 .button({icons: {primary: 'ui-icon-trash'}})556 513 .bind('click.' + ns, function (e) { 557 514 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); 559 519 }); 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 () { 570 530 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); 573 569 }, 574 570 575 571 _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'); 583 575 }, 584 576 585 577 _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'); 593 581 }, 594 582 595 583 _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(); 610 611 }, 611 612 612 613 _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 634 628 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); 638 631 this._enableFileInputButton(); 639 632 }, 640 633 641 634 disable: function () { 642 this.element.find(':ui-button').not('.fileinput-button') 643 .button('disable'); 635 this.element.find('input, button').prop('disabled', true); 644 636 this._disableFileInputButton(); 645 $.blueimp.fileupload.prototype.disable.call(this);637 parentWidget.prototype.disable.call(this); 646 638 } 647 639 648 640 }); 649 641 650 } (jQuery));642 })); -
trunk/prototype/plugins/fileupload/jquery.fileupload.js
r5341 r6107 1 1 /* 2 * jQuery File Upload Plugin 5. 22 * jQuery File Upload Plugin 5.10.1 3 3 * https://github.com/blueimp/jQuery-File-Upload 4 4 * … … 7 7 * 8 8 * Licensed under the MIT license: 9 * http:// creativecommons.org/licenses/MIT/9 * http://www.opensource.org/licenses/MIT 10 10 */ 11 11 12 12 /*jslint nomen: true, unparam: true, regexp: true */ 13 /*global d ocument, XMLHttpRequestUpload, Blob, File, FormData, location, jQuery*/14 15 (function ( $) {13 /*global define, window, document, Blob, FormData, location */ 14 15 (function (factory) { 16 16 '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. 20 38 // 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 // usingthe fileupload API.23 // By default, files added via file input selection, drag & drop or39 // 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 24 42 // "add" method are uploaded immediately, but it is possible to override 25 43 // the "add" callback option to queue file uploads. 26 44 $.widget('blueimp.fileupload', { 27 45 28 46 options: { 29 47 // The namespace used for event handler binding on the dropZone and … … 46 64 // The parameter name for the file form data (the request argument name). 47 65 // 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: 49 68 paramName: undefined, 50 69 // By default, each file of a selection is uploaded using an individual … … 63 82 // Set the following option to true to force iframe transport uploads: 64 83 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, 65 93 // By default, XHR file uploads are sent as multipart/form-data. 66 94 // The iframe transport is always using multipart/form-data. … … 82 110 // prevent recalculating the global progress data: 83 111 recalculateProgress: true, 84 112 85 113 // Additional form data to be sent along with the file uploads can be set 86 114 // using this option, which accepts an array of objects with name and … … 91 119 return form.serializeArray(); 92 120 }, 93 121 94 122 // 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). 96 124 // If the singleFileUploads option is enabled, this callback will be 97 125 // called once for each file in the selection for XHR file uplaods, else … … 108 136 data.submit(); 109 137 }, 110 138 111 139 // Other callbacks: 140 // Callback for the submit event of each file upload: 141 // submit: function (e, data) {}, // .bind('fileuploadsubmit', func); 112 142 // Callback for the start of each file upload request: 113 143 // send: function (e, data) {}, // .bind('fileuploadsend', func); … … 128 158 // Callback for change events of the fileInput collection: 129 159 // change: function (e, data) {}, // .bind('fileuploadchange', func); 160 // Callback for paste events to the dropZone collection: 161 // paste: function (e, data) {}, // .bind('fileuploadpaste', func); 130 162 // Callback for drop events of the dropZone collection: 131 163 // drop: function (e, data) {}, // .bind('fileuploaddrop', func); 132 164 // Callback for dragover events of the dropZone collection: 133 165 // dragover: function (e) {}, // .bind('fileuploaddragover', func); 134 166 135 167 // The plugin options are used as settings object for the ajax calls. 136 168 // The following are jQuery ajax settings required for the file uploads: … … 139 171 cache: false 140 172 }, 141 173 142 174 // 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 ], 144 182 145 183 _isXHRUpload: function (options) { 146 var undef = 'undefined';147 184 return !options.forceIframeTransport && 148 typeof XMLHttpRequestUpload !== undef && typeof File !== undef &&149 (!options.multipart || typeof FormData !== undef);185 ((!options.multipart && $.support.xhrFileUpload) || 186 $.support.xhrFormDataFileUpload); 150 187 }, 151 188 … … 204 241 // Accesss to the native XHR object is required to add event listeners 205 242 // 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; 208 250 that._onProgress(e, options); 209 } , false);251 }); 210 252 options.xhr = function () { 211 253 return xhr; … … 216 258 _initXHRData: function (options) { 217 259 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) { 220 265 // For non-multipart uploads and chunked uploads, 221 266 // file meta data is not part of the request body, … … 233 278 options.contentType = file.type; 234 279 options.data = file; 235 } else if (! options.multipart) {280 } else if (!multipart) { 236 281 // Chunked non-multipart upload: 237 282 options.contentType = 'application/octet-stream'; … … 239 284 } 240 285 } 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 } 244 306 } 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 } 261 331 } 262 332 options.data = formData; … … 265 335 options.blob = null; 266 336 }, 267 337 268 338 _initIframeSettings: function (options) { 269 339 // Setting the dataType to iframe enables the iframe transport: … … 271 341 // The iframe transport accepts a serialized array as form data: 272 342 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 275 353 _initDataSettings: function (options) { 276 354 if (this._isXHRUpload(options)) { … … 281 359 this._initProgressListener(options); 282 360 } 361 if (options.postMessage) { 362 // Setting the dataType to postmessage enables the 363 // postMessage transport: 364 options.dataType = 'postmessage ' + (options.dataType || ''); 365 } 283 366 } 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 288 394 _initFormSettings: function (options) { 289 395 // Retrieve missing options from the input field and the … … 292 398 options.form = $(options.fileInput.prop('form')); 293 399 } 294 if (!options.paramName) { 295 options.paramName = options.fileInput.prop('name') || 296 'files[]'; 297 } 400 options.paramName = this._getParamName(options); 298 401 if (!options.url) { 299 402 options.url = options.form.prop('action') || location.href; … … 306 409 } 307 410 }, 308 411 309 412 _getAJAXSettings: function (data) { 310 413 var options = $.extend({}, this.options, data); … … 365 468 if (ub >= fs) { 366 469 file.error = 'uploadedBytes'; 367 return this._getXHRPromise(false); 470 return this._getXHRPromise( 471 false, 472 options.context, 473 [null, 'error', file.error] 474 ); 368 475 } 369 476 // n is the number of blobs to upload, … … 373 480 upload = function (i) { 374 481 if (!i) { 375 return that._getXHRPromise(true );482 return that._getXHRPromise(true, options.context); 376 483 } 377 484 // Upload the blobs in sequential order: … … 402 509 }), o); 403 510 } 404 options.uploadedBytes = o.uploadedBytes 405 +=o.chunkSize;511 options.uploadedBytes = o.uploadedBytes += 512 o.chunkSize; 406 513 }); 407 514 return jqXHR; … … 459 566 }, 460 567 461 _onAlways: function ( result, textStatus, jqXHR, errorThrown, options) {568 _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { 462 569 this._active -= 1; 463 options.result = result;464 570 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 } 467 578 this._trigger('always', null, options); 468 579 if (this._active === 0) { … … 492 603 }).fail(function (jqXHR, textStatus, errorThrown) { 493 604 that._onFail(jqXHR, textStatus, errorThrown, options); 494 }).always(function ( a1, a2, a3) {605 }).always(function (jqXHRorResult, textStatus, jqXHRorError) { 495 606 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 ); 501 613 if (options.limitConcurrentUploads && 502 614 options.limitConcurrentUploads > that._sending) { … … 543 655 return send(); 544 656 }, 545 657 546 658 _onAdd: function (e, data) { 547 659 var that = this, 548 660 result = true, 549 661 options = $.extend({}, this.options, data), 550 fileSet = data.files,551 662 limit = options.limitMultiFileUploads, 663 paramName = this._getParamName(options), 664 paramNameSet, 665 paramNameSlice, 666 fileSet, 552 667 i; 553 668 if (!(options.singleFileUploads || limit) || 554 669 !this._isXHRUpload(options)) { 555 fileSet = [fileSet]; 670 fileSet = [data.files]; 671 paramNameSet = [paramName]; 556 672 } else if (!options.singleFileUploads && limit) { 557 673 fileSet = []; 674 paramNameSet = []; 558 675 for (i = 0; i < data.files.length; i += limit) { 559 676 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]; 565 691 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; 567 696 }; 568 697 return (result = that._trigger('add', e, newData)); … … 570 699 return result; 571 700 }, 572 701 573 702 // File Normalization for Gecko 1.9.1 (Firefox 3.5) support: 574 703 _normalizeFile: function (index, file) { … … 585 714 // without loosing the file input value: 586 715 input.after(inputClone).detach(); 716 // Avoid memory leaks with the detached file input: 717 $.cleanData(input.unbind('remove')); 587 718 // Replace the original file input element in the fileInput 588 719 // collection with the clone, which has been copied including … … 594 725 return el; 595 726 }); 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 598 734 _onChange: function (e) { 599 735 var that = e.data.fileupload, … … 609 745 data.files = [{name: e.target.value.replace(/^.*\\/, '')}]; 610 746 } 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 }618 747 if (that.options.replaceFileInput) { 619 748 that._replaceFileInput(data.fileInput); … … 624 753 } 625 754 }, 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 627 773 _onDrop: function (e) { 628 774 var that = e.data.fileupload, … … 640 786 e.preventDefault(); 641 787 }, 642 788 643 789 _onDragOver: function (e) { 644 790 var that = e.data.fileupload, … … 652 798 e.preventDefault(); 653 799 }, 654 800 655 801 _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 } 660 809 this.options.fileInput 661 810 .bind('change.' + ns, {fileupload: this}, this._onChange); … … 663 812 664 813 _destroyEventHandlers: function () { 665 var ns = this.options.namespace || this.name;814 var ns = this.options.namespace; 666 815 this.options.dropZone 667 816 .unbind('dragover.' + ns, this._onDragOver) 668 .unbind('drop.' + ns, this._onDrop); 817 .unbind('drop.' + ns, this._onDrop) 818 .unbind('paste.' + ns, this._onPaste); 669 819 this.options.fileInput 670 820 .unbind('change.' + ns, this._onChange); 671 821 }, 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 688 823 _setOption: function (key, value) { 689 824 var refresh = $.inArray(key, this._refreshOptionsList) !== -1; 690 825 if (refresh) { 691 this._ beforeSetOption(key, value);826 this._destroyEventHandlers(); 692 827 } 693 828 $.Widget.prototype._setOption.call(this, key, value); 694 829 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 () { 700 836 var options = this.options; 701 837 if (options.fileInput === undefined) { 702 838 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(); 710 854 this._slots = []; 711 855 this._sequence = this._getXHRPromise(true); … … 713 857 this._initEventHandlers(); 714 858 }, 715 859 716 860 destroy: function () { 717 861 this._destroyEventHandlers(); … … 723 867 this._initEventHandlers(); 724 868 }, 725 869 726 870 disable: function () { 727 871 this._destroyEventHandlers(); … … 740 884 this._onAdd(null, data); 741 885 }, 742 886 743 887 // This method is exposed to the widget API and allows sending files 744 888 // using the fileupload API. The data parameter accepts an object which … … 755 899 return this._getXHRPromise(false, data && data.context); 756 900 } 757 901 758 902 }); 759 760 } (jQuery));903 904 })); -
trunk/prototype/plugins/fileupload/jquery.iframe-transport.js
r5341 r6107 1 1 /* 2 * jQuery Iframe Transport Plugin 1. 2.22 * jQuery Iframe Transport Plugin 1.4 3 3 * https://github.com/blueimp/jQuery-File-Upload 4 4 * … … 7 7 * 8 8 * Licensed under the MIT license: 9 * http:// creativecommons.org/licenses/MIT/9 * http://www.opensource.org/licenses/MIT 10 10 */ 11 11 12 /*jslint unparam: true */13 /*global jQuery*/12 /*jslint unparam: true, nomen: true */ 13 /*global define, window, document */ 14 14 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 ($) { 16 25 'use strict'; 17 26 … … 22 31 // options.fileInput: a jQuery collection of file input fields 23 32 // 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. 25 35 // options.formData: an array of objects with name and value properties, 26 36 // 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')) { 30 40 var form, 31 41 iframe; 32 42 return { 33 send: function ( headers, completeCallback) {43 send: function (_, completeCallback) { 34 44 form = $('<form style="display:none;"></form>'); 35 45 // javascript:false as initial iframe src … … 42 52 (counter += 1) + '"></iframe>' 43 53 ).bind('load', function () { 44 var fileInputClones; 54 var fileInputClones, 55 paramNames = $.isArray(options.paramName) ? 56 options.paramName : [options.paramName]; 45 57 iframe 46 58 .unbind('load') … … 93 105 }); 94 106 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 ); 97 112 }); 98 113 } … … 116 131 } 117 132 }); 118 form.append(iframe).appendTo( 'body');133 form.append(iframe).appendTo(document.body); 119 134 }, 120 135 abort: function () { … … 140 155 converters: { 141 156 'iframe text': function (iframe) { 142 return iframe.text();157 return $(iframe[0].body).text(); 143 158 }, 144 159 'iframe json': function (iframe) { 145 return $.parseJSON( iframe.text());160 return $.parseJSON($(iframe[0].body).text()); 146 161 }, 147 162 'iframe html': function (iframe) { 148 return iframe.find('body').html();163 return $(iframe[0].body).html(); 149 164 }, 150 165 'iframe script': function (iframe) { 151 return $.globalEval( iframe.text());166 return $.globalEval($(iframe[0].body).text()); 152 167 } 153 168 } 154 169 }); 155 170 156 } (jQuery));171 }));
Note: See TracChangeset
for help on using the changeset viewer.