cms/drupal/modules/file/file.js
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     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  */
       
    15 Drupal.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  */
       
    36 Drupal.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  */
       
    50 Drupal.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  */
       
    62 Drupal.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);