annotate .svn/pristine/87/878e6d0272e02b1ea64a3a823a8221bf835c94b4.svn-base @ 1524:82fac3dcf466 redmine-2.5-integration

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