Mercurial > hg > soundsoftware-site
comparison .svn/pristine/c9/c9a4606fd56695d0574a554ddcfcebb976dd9120.svn-base @ 1516:b450a9d58aed redmine-2.4
Update to Redmine SVN revision 13356 on 2.4-stable branch
author | Chris Cannam |
---|---|
date | Tue, 09 Sep 2014 09:28:31 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1494:e248c7af89ec | 1516:b450a9d58aed |
---|---|
1 /* Redmine - project management software | |
2 Copyright (C) 2006-2014 Jean-Philippe Lang */ | |
3 | |
4 function addFile(inputEl, file, eagerUpload) { | |
5 | |
6 if ($('#attachments_fields').children().length < 10) { | |
7 | |
8 var attachmentId = addFile.nextAttachmentId++; | |
9 | |
10 var fileSpan = $('<span>', { id: 'attachments_' + attachmentId }); | |
11 | |
12 fileSpan.append( | |
13 $('<input>', { type: 'text', 'class': 'filename readonly', name: 'attachments[' + attachmentId + '][filename]', readonly: 'readonly'} ).val(file.name), | |
14 $('<input>', { type: 'text', 'class': 'description', name: 'attachments[' + attachmentId + '][description]', maxlength: 255, placeholder: $(inputEl).data('description-placeholder') } ).toggle(!eagerUpload), | |
15 $('<a> </a>').attr({ href: "#", 'class': 'remove-upload' }).click(removeFile).toggle(!eagerUpload) | |
16 ).appendTo('#attachments_fields'); | |
17 | |
18 if(eagerUpload) { | |
19 ajaxUpload(file, attachmentId, fileSpan, inputEl); | |
20 } | |
21 | |
22 return attachmentId; | |
23 } | |
24 return null; | |
25 } | |
26 | |
27 addFile.nextAttachmentId = 1; | |
28 | |
29 function ajaxUpload(file, attachmentId, fileSpan, inputEl) { | |
30 | |
31 function onLoadstart(e) { | |
32 fileSpan.removeClass('ajax-waiting'); | |
33 fileSpan.addClass('ajax-loading'); | |
34 $('input:submit', $(this).parents('form')).attr('disabled', 'disabled'); | |
35 } | |
36 | |
37 function onProgress(e) { | |
38 if(e.lengthComputable) { | |
39 this.progressbar( 'value', e.loaded * 100 / e.total ); | |
40 } | |
41 } | |
42 | |
43 function actualUpload(file, attachmentId, fileSpan, inputEl) { | |
44 | |
45 ajaxUpload.uploading++; | |
46 | |
47 uploadBlob(file, $(inputEl).data('upload-path'), attachmentId, { | |
48 loadstartEventHandler: onLoadstart.bind(progressSpan), | |
49 progressEventHandler: onProgress.bind(progressSpan) | |
50 }) | |
51 .done(function(result) { | |
52 progressSpan.progressbar( 'value', 100 ).remove(); | |
53 fileSpan.find('input.description, a').css('display', 'inline-block'); | |
54 }) | |
55 .fail(function(result) { | |
56 progressSpan.text(result.statusText); | |
57 }).always(function() { | |
58 ajaxUpload.uploading--; | |
59 fileSpan.removeClass('ajax-loading'); | |
60 var form = fileSpan.parents('form'); | |
61 if (form.queue('upload').length == 0 && ajaxUpload.uploading == 0) { | |
62 $('input:submit', form).removeAttr('disabled'); | |
63 } | |
64 form.dequeue('upload'); | |
65 }); | |
66 } | |
67 | |
68 var progressSpan = $('<div>').insertAfter(fileSpan.find('input.filename')); | |
69 progressSpan.progressbar(); | |
70 fileSpan.addClass('ajax-waiting'); | |
71 | |
72 var maxSyncUpload = $(inputEl).data('max-concurrent-uploads'); | |
73 | |
74 if(maxSyncUpload == null || maxSyncUpload <= 0 || ajaxUpload.uploading < maxSyncUpload) | |
75 actualUpload(file, attachmentId, fileSpan, inputEl); | |
76 else | |
77 $(inputEl).parents('form').queue('upload', actualUpload.bind(this, file, attachmentId, fileSpan, inputEl)); | |
78 } | |
79 | |
80 ajaxUpload.uploading = 0; | |
81 | |
82 function removeFile() { | |
83 $(this).parent('span').remove(); | |
84 return false; | |
85 } | |
86 | |
87 function uploadBlob(blob, uploadUrl, attachmentId, options) { | |
88 | |
89 var actualOptions = $.extend({ | |
90 loadstartEventHandler: $.noop, | |
91 progressEventHandler: $.noop | |
92 }, options); | |
93 | |
94 uploadUrl = uploadUrl + '?attachment_id=' + attachmentId; | |
95 if (blob instanceof window.File) { | |
96 uploadUrl += '&filename=' + encodeURIComponent(blob.name); | |
97 } | |
98 | |
99 return $.ajax(uploadUrl, { | |
100 type: 'POST', | |
101 contentType: 'application/octet-stream', | |
102 beforeSend: function(jqXhr, settings) { | |
103 jqXhr.setRequestHeader('Accept', 'application/js'); | |
104 // attach proper File object | |
105 settings.data = blob; | |
106 }, | |
107 xhr: function() { | |
108 var xhr = $.ajaxSettings.xhr(); | |
109 xhr.upload.onloadstart = actualOptions.loadstartEventHandler; | |
110 xhr.upload.onprogress = actualOptions.progressEventHandler; | |
111 return xhr; | |
112 }, | |
113 data: blob, | |
114 cache: false, | |
115 processData: false | |
116 }); | |
117 } | |
118 | |
119 function addInputFiles(inputEl) { | |
120 var clearedFileInput = $(inputEl).clone().val(''); | |
121 | |
122 if (inputEl.files) { | |
123 // upload files using ajax | |
124 uploadAndAttachFiles(inputEl.files, inputEl); | |
125 $(inputEl).remove(); | |
126 } else { | |
127 // browser not supporting the file API, upload on form submission | |
128 var attachmentId; | |
129 var aFilename = inputEl.value.split(/\/|\\/); | |
130 attachmentId = addFile(inputEl, { name: aFilename[ aFilename.length - 1 ] }, false); | |
131 if (attachmentId) { | |
132 $(inputEl).attr({ name: 'attachments[' + attachmentId + '][file]', style: 'display:none;' }).appendTo('#attachments_' + attachmentId); | |
133 } | |
134 } | |
135 | |
136 clearedFileInput.insertAfter('#attachments_fields').on('change', function(){addInputFiles(this);}); | |
137 } | |
138 | |
139 function uploadAndAttachFiles(files, inputEl) { | |
140 | |
141 var maxFileSize = $(inputEl).data('max-file-size'); | |
142 var maxFileSizeExceeded = $(inputEl).data('max-file-size-message'); | |
143 | |
144 var sizeExceeded = false; | |
145 $.each(files, function() { | |
146 if (this.size && maxFileSize != null && this.size > parseInt(maxFileSize)) {sizeExceeded=true;} | |
147 }); | |
148 if (sizeExceeded) { | |
149 window.alert(maxFileSizeExceeded); | |
150 } else { | |
151 $.each(files, function() {addFile(inputEl, this, true);}); | |
152 } | |
153 } | |
154 | |
155 function handleFileDropEvent(e) { | |
156 | |
157 $(this).removeClass('fileover'); | |
158 blockEventPropagation(e); | |
159 | |
160 if ($.inArray('Files', e.dataTransfer.types) > -1) { | |
161 uploadAndAttachFiles(e.dataTransfer.files, $('input:file.file_selector')); | |
162 } | |
163 } | |
164 | |
165 function dragOverHandler(e) { | |
166 $(this).addClass('fileover'); | |
167 blockEventPropagation(e); | |
168 } | |
169 | |
170 function dragOutHandler(e) { | |
171 $(this).removeClass('fileover'); | |
172 blockEventPropagation(e); | |
173 } | |
174 | |
175 function setupFileDrop() { | |
176 if (window.File && window.FileList && window.ProgressEvent && window.FormData) { | |
177 | |
178 $.event.fixHooks.drop = { props: [ 'dataTransfer' ] }; | |
179 | |
180 $('form div.box').has('input:file').each(function() { | |
181 $(this).on({ | |
182 dragover: dragOverHandler, | |
183 dragleave: dragOutHandler, | |
184 drop: handleFileDropEvent | |
185 }); | |
186 }); | |
187 } | |
188 } | |
189 | |
190 $(document).ready(setupFileDrop); |