1/** 2 * @file 3 * Provides JavaScript additions to the managed file field type. 4 * 5 * This file provides progress bar support (if available), popup windows for 6 * file previews, and disabling of other file fields during Ajax uploads (which 7 * prevents separate file fields from accidentally uploading files). 8 */ 9 10(function ($) { 11 12/** 13 * Attach behaviors to managed file element upload fields. 14 */ 15Drupal.behaviors.fileValidateAutoAttach = { 16 attach: function (context, settings) { 17 if (settings.file && settings.file.elements) { 18 $.each(settings.file.elements, function(selector) { 19 var extensions = settings.file.elements[selector]; 20 $(selector, context).bind('change', {extensions: extensions}, Drupal.file.validateExtension); 21 }); 22 } 23 }, 24 detach: function (context, settings) { 25 if (settings.file && settings.file.elements) { 26 $.each(settings.file.elements, function(selector) { 27 $(selector, context).unbind('change', Drupal.file.validateExtension); 28 }); 29 } 30 } 31}; 32 33/** 34 * Attach behaviors to the file upload and remove buttons. 35 */ 36Drupal.behaviors.fileButtons = { 37 attach: function (context) { 38 $('input.form-submit', context).bind('mousedown', Drupal.file.disableFields); 39 $('div.form-managed-file input.form-submit', context).bind('mousedown', Drupal.file.progressBar); 40 }, 41 detach: function (context) { 42 $('input.form-submit', context).unbind('mousedown', Drupal.file.disableFields); 43 $('div.form-managed-file input.form-submit', context).unbind('mousedown', Drupal.file.progressBar); 44 } 45}; 46 47/** 48 * Attach behaviors to links within managed file elements. 49 */ 50Drupal.behaviors.filePreviewLinks = { 51 attach: function (context) { 52 $('div.form-managed-file .file a, .file-widget .file a', context).bind('click',Drupal.file.openInNewWindow); 53 }, 54 detach: function (context){ 55 $('div.form-managed-file .file a, .file-widget .file a', context).unbind('click', Drupal.file.openInNewWindow); 56 } 57}; 58 59/** 60 * File upload utility functions. 61 */ 62Drupal.file = Drupal.file || { 63 /** 64 * Client-side file input validation of file extensions. 65 */ 66 validateExtension: function (event) { 67 // Remove any previous errors. 68 $('.file-upload-js-error').remove(); 69 70 // Add client side validation for the input[type=file]. 71 var extensionPattern = event.data.extensions.replace(/,\s*/g, '|'); 72 if (extensionPattern.length > 1 && this.value.length > 0) { 73 var acceptableMatch = new RegExp('\\.(' + extensionPattern + ')$', 'gi'); 74 if (!acceptableMatch.test(this.value)) { 75 var error = Drupal.t("The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.", { 76 // According to the specifications of HTML5, a file upload control 77 // should not reveal the real local path to the file that a user 78 // has selected. Some web browsers implement this restriction by 79 // replacing the local path with "C:\fakepath\", which can cause 80 // confusion by leaving the user thinking perhaps Drupal could not 81 // find the file because it messed up the file path. To avoid this 82 // confusion, therefore, we strip out the bogus fakepath string. 83 '%filename': this.value.replace('C:\\fakepath\\', ''), 84 '%extensions': extensionPattern.replace(/\|/g, ', ') 85 }); 86 $(this).closest('div.form-managed-file').prepend('<div class="messages error file-upload-js-error" aria-live="polite">' + error + '</div>'); 87 this.value = ''; 88 return false; 89 } 90 } 91 }, 92 /** 93 * Prevent file uploads when using buttons not intended to upload. 94 */ 95 disableFields: function (event){ 96 var clickedButton = this; 97 98 // Only disable upload fields for Ajax buttons. 99 if (!$(clickedButton).hasClass('ajax-processed')) { 100 return; 101 } 102 103 // Check if we're working with an "Upload" button. 104 var $enabledFields = []; 105 if ($(this).closest('div.form-managed-file').length > 0) { 106 $enabledFields = $(this).closest('div.form-managed-file').find('input.form-file'); 107 } 108 109 // Temporarily disable upload fields other than the one we're currently 110 // working with. Filter out fields that are already disabled so that they 111 // do not get enabled when we re-enable these fields at the end of behavior 112 // processing. Re-enable in a setTimeout set to a relatively short amount
113 // of time (1 second). All the other mousedown handlers (like Drupal's Ajax 114 // behaviors) are excuted before any timeout functions are called, so we 115 // don't have to worry about the fields being re-enabled too soon. 116 // @todo If the previous sentence is true, why not set the timeout to 0? 117 var $fieldsToTemporarilyDisable = $('div.form-managed-file input.form-file').not($enabledFields).not(':disabled'); 118 $fieldsToTemporarilyDisable.attr('disabled', 'disabled'); 119 setTimeout(function (){ 120 $fieldsToTemporarilyDisable.attr('disabled', false); 121 }, 1000); 122 }, 123 /** 124 * Add progress bar support if possible. 125 */ 126 progressBar: function (event) { 127 var clickedButton = this; 128 var $progressId = $(clickedButton).closest('div.form-managed-file').find('input.file-progress'); 129 if ($progressId.length) { 130 var originalName = $progressId.attr('name'); 131 132 // Replace the name with the required identifier. 133 $progressId.attr('name', originalName.match(/APC_UPLOAD_PROGRESS|UPLOAD_IDENTIFIER/)[0]); 134 135 // Restore the original name after the upload begins. 136 setTimeout(function () { 137 $progressId.attr('name', originalName); 138 }, 1000); 139 } 140 // Show the progress bar if the upload takes longer than half a second. 141 setTimeout(function () { 142 $(clickedButton).closest('div.form-managed-file').find('div.ajax-progress-bar').slideDown(); 143 }, 500); 144 }, 145 /** 146 * Open links to files within forms in a new window. 147 */ 148 openInNewWindow: function (event) { 149 $(this).attr('target', '_blank'); 150 window.open(this.href, 'filePreview', 'toolbar=0,scrollbars=1,location=1,statusbar=1,menubar=0,resizable=1,width=500,height=550'); 151 return false; 152 } 153}; 154 155})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.