github.com/apremalal/vamps-core@v1.0.1-0.20161221121535-d430b56ec174/server/webapps/app/base/plugins/jquery-file-upload/js/jquery.fileupload-angular.js (about)

     1  /*
     2   * jQuery File Upload AngularJS Plugin 2.2.0
     3   * https://github.com/blueimp/jQuery-File-Upload
     4   *
     5   * Copyright 2013, Sebastian Tschan
     6   * https://blueimp.net
     7   *
     8   * Licensed under the MIT license:
     9   * http://www.opensource.org/licenses/MIT
    10   */
    11  
    12  /* jshint nomen:false */
    13  /* global define, angular */
    14  
    15  (function (factory) {
    16      'use strict';
    17      if (typeof define === 'function' && define.amd) {
    18          // Register as an anonymous AMD module:
    19          define([
    20              'jquery',
    21              'angular',
    22              './jquery.fileupload-image.js',
    23              './jquery.fileupload-audio',
    24              './jquery.fileupload-video',
    25              './jquery.fileupload-validate'
    26          ], factory);
    27      } else {
    28          factory();
    29      }
    30  }(function () {
    31      'use strict';
    32  
    33      angular.module('blueimp.fileupload', [])
    34  
    35          // The fileUpload service provides configuration options
    36          // for the fileUpload directive and default handlers for
    37          // File Upload events:
    38          .provider('fileUpload', function () {
    39              var scopeEvalAsync = function (expression) {
    40                      var scope = angular.element(this)
    41                              .fileupload('option', 'scope');
    42                      // Schedule a new $digest cycle if not already inside of one
    43                      // and evaluate the given expression:
    44                      scope.$evalAsync(expression);
    45                  },
    46                  addFileMethods = function (scope, data) {
    47                      var files = data.files,
    48                          file = files[0];
    49                      angular.forEach(files, function (file, index) {
    50                          file._index = index;
    51                          file.$state = function () {
    52                              return data.state();
    53                          };
    54                          file.$processing = function () {
    55                              return data.processing();
    56                          };
    57                          file.$progress = function () {
    58                              return data.progress();
    59                          };
    60                          file.$response = function () {
    61                              return data.response();
    62                          };
    63                      });
    64                      file.$submit = function () {
    65                          if (!file.error) {
    66                              return data.submit();
    67                          }
    68                      };
    69                      file.$cancel = function () {
    70                          return data.abort();
    71                      };
    72                  },
    73                  $config;
    74              $config = this.defaults = {
    75                  handleResponse: function (e, data) {
    76                      var files = data.result && data.result.files;
    77                      if (files) {
    78                          data.scope.replace(data.files, files);
    79                      } else if (data.errorThrown ||
    80                              data.textStatus === 'error') {
    81                          data.files[0].error = data.errorThrown ||
    82                              data.textStatus;
    83                      }
    84                  },
    85                  add: function (e, data) {
    86                      if (e.isDefaultPrevented()) {
    87                          return false;
    88                      }
    89                      var scope = data.scope,
    90                          filesCopy = [];
    91                      angular.forEach(data.files, function (file) {
    92                          filesCopy.push(file);
    93                      });
    94                      scope.$apply(function () {
    95                          addFileMethods(scope, data);
    96                          var method = scope.option('prependFiles') ?
    97                                  'unshift' : 'push';
    98                          Array.prototype[method].apply(scope.queue, data.files);
    99                      });
   100                      data.process(function () {
   101                          return scope.process(data);
   102                      }).always(function () {
   103                          scope.$apply(function () {
   104                              addFileMethods(scope, data);
   105                              scope.replace(filesCopy, data.files);
   106                          });
   107                      }).then(function () {
   108                          if ((scope.option('autoUpload') ||
   109                                  data.autoUpload) &&
   110                                  data.autoUpload !== false) {
   111                              data.submit();
   112                          }
   113                      });
   114                  },
   115                  progress: function (e, data) {
   116                      if (e.isDefaultPrevented()) {
   117                          return false;
   118                      }
   119                      data.scope.$apply();
   120                  },
   121                  done: function (e, data) {
   122                      if (e.isDefaultPrevented()) {
   123                          return false;
   124                      }
   125                      var that = this;
   126                      data.scope.$apply(function () {
   127                          data.handleResponse.call(that, e, data);
   128                      });
   129                  },
   130                  fail: function (e, data) {
   131                      if (e.isDefaultPrevented()) {
   132                          return false;
   133                      }
   134                      var that = this,
   135                          scope = data.scope;
   136                      if (data.errorThrown === 'abort') {
   137                          scope.clear(data.files);
   138                          return;
   139                      }
   140                      scope.$apply(function () {
   141                          data.handleResponse.call(that, e, data);
   142                      });
   143                  },
   144                  stop: scopeEvalAsync,
   145                  processstart: scopeEvalAsync,
   146                  processstop: scopeEvalAsync,
   147                  getNumberOfFiles: function () {
   148                      var scope = this.scope;
   149                      return scope.queue.length - scope.processing();
   150                  },
   151                  dataType: 'json',
   152                  autoUpload: false
   153              };
   154              this.$get = [
   155                  function () {
   156                      return {
   157                          defaults: $config
   158                      };
   159                  }
   160              ];
   161          })
   162  
   163          // Format byte numbers to readable presentations:
   164          .provider('formatFileSizeFilter', function () {
   165              var $config = {
   166                  // Byte units following the IEC format
   167                  // http://en.wikipedia.org/wiki/Kilobyte
   168                  units: [
   169                      {size: 1000000000, suffix: ' GB'},
   170                      {size: 1000000, suffix: ' MB'},
   171                      {size: 1000, suffix: ' KB'}
   172                  ]
   173              };
   174              this.defaults = $config;
   175              this.$get = function () {
   176                  return function (bytes) {
   177                      if (!angular.isNumber(bytes)) {
   178                          return '';
   179                      }
   180                      var unit = true,
   181                          i = 0,
   182                          prefix,
   183                          suffix;
   184                      while (unit) {
   185                          unit = $config.units[i];
   186                          prefix = unit.prefix || '';
   187                          suffix = unit.suffix || '';
   188                          if (i === $config.units.length - 1 || bytes >= unit.size) {
   189                              return prefix + (bytes / unit.size).toFixed(2) + suffix;
   190                          }
   191                          i += 1;
   192                      }
   193                  };
   194              };
   195          })
   196  
   197          // The FileUploadController initializes the fileupload widget and
   198          // provides scope methods to control the File Upload functionality:
   199          .controller('FileUploadController', [
   200              '$scope', '$element', '$attrs', '$window', 'fileUpload',
   201              function ($scope, $element, $attrs, $window, fileUpload) {
   202                  var uploadMethods = {
   203                      progress: function () {
   204                          return $element.fileupload('progress');
   205                      },
   206                      active: function () {
   207                          return $element.fileupload('active');
   208                      },
   209                      option: function (option, data) {
   210                          if (arguments.length === 1) {
   211                              return $element.fileupload('option', option);
   212                          }
   213                          $element.fileupload('option', option, data);
   214                      },
   215                      add: function (data) {
   216                          return $element.fileupload('add', data);
   217                      },
   218                      send: function (data) {
   219                          return $element.fileupload('send', data);
   220                      },
   221                      process: function (data) {
   222                          return $element.fileupload('process', data);
   223                      },
   224                      processing: function (data) {
   225                          return $element.fileupload('processing', data);
   226                      }
   227                  };
   228                  $scope.disabled = !$window.jQuery.support.fileInput;
   229                  $scope.queue = $scope.queue || [];
   230                  $scope.clear = function (files) {
   231                      var queue = this.queue,
   232                          i = queue.length,
   233                          file = files,
   234                          length = 1;
   235                      if (angular.isArray(files)) {
   236                          file = files[0];
   237                          length = files.length;
   238                      }
   239                      while (i) {
   240                          i -= 1;
   241                          if (queue[i] === file) {
   242                              return queue.splice(i, length);
   243                          }
   244                      }
   245                  };
   246                  $scope.replace = function (oldFiles, newFiles) {
   247                      var queue = this.queue,
   248                          file = oldFiles[0],
   249                          i,
   250                          j;
   251                      for (i = 0; i < queue.length; i += 1) {
   252                          if (queue[i] === file) {
   253                              for (j = 0; j < newFiles.length; j += 1) {
   254                                  queue[i + j] = newFiles[j];
   255                              }
   256                              return;
   257                          }
   258                      }
   259                  };
   260                  $scope.applyOnQueue = function (method) {
   261                      var list = this.queue.slice(0),
   262                          i,
   263                          file;
   264                      for (i = 0; i < list.length; i += 1) {
   265                          file = list[i];
   266                          if (file[method]) {
   267                              file[method]();
   268                          }
   269                      }
   270                  };
   271                  $scope.submit = function () {
   272                      this.applyOnQueue('$submit');
   273                  };
   274                  $scope.cancel = function () {
   275                      this.applyOnQueue('$cancel');
   276                  };
   277                  // Add upload methods to the scope:
   278                  angular.extend($scope, uploadMethods);
   279                  // The fileupload widget will initialize with
   280                  // the options provided via "data-"-parameters,
   281                  // as well as those given via options object:
   282                  $element.fileupload(angular.extend(
   283                      {scope: $scope},
   284                      fileUpload.defaults
   285                  )).on('fileuploadadd', function (e, data) {
   286                      data.scope = $scope;
   287                  }).on('fileuploadfail', function (e, data) {
   288                      if (data.errorThrown === 'abort') {
   289                          return;
   290                      }
   291                      if (data.dataType &&
   292                              data.dataType.indexOf('json') === data.dataType.length - 4) {
   293                          try {
   294                              data.result = angular.fromJson(data.jqXHR.responseText);
   295                          } catch (ignore) {}
   296                      }
   297                  }).on([
   298                      'fileuploadadd',
   299                      'fileuploadsubmit',
   300                      'fileuploadsend',
   301                      'fileuploaddone',
   302                      'fileuploadfail',
   303                      'fileuploadalways',
   304                      'fileuploadprogress',
   305                      'fileuploadprogressall',
   306                      'fileuploadstart',
   307                      'fileuploadstop',
   308                      'fileuploadchange',
   309                      'fileuploadpaste',
   310                      'fileuploaddrop',
   311                      'fileuploaddragover',
   312                      'fileuploadchunksend',
   313                      'fileuploadchunkdone',
   314                      'fileuploadchunkfail',
   315                      'fileuploadchunkalways',
   316                      'fileuploadprocessstart',
   317                      'fileuploadprocess',
   318                      'fileuploadprocessdone',
   319                      'fileuploadprocessfail',
   320                      'fileuploadprocessalways',
   321                      'fileuploadprocessstop'
   322                  ].join(' '), function (e, data) {
   323                      if ($scope.$emit(e.type, data).defaultPrevented) {
   324                          e.preventDefault();
   325                      }
   326                  }).on('remove', function () {
   327                      // Remove upload methods from the scope,
   328                      // when the widget is removed:
   329                      var method;
   330                      for (method in uploadMethods) {
   331                          if (uploadMethods.hasOwnProperty(method)) {
   332                              delete $scope[method];
   333                          }
   334                      }
   335                  });
   336                  // Observe option changes:
   337                  $scope.$watch(
   338                      $attrs.fileUpload,
   339                      function (newOptions) {
   340                          if (newOptions) {
   341                              $element.fileupload('option', newOptions);
   342                          }
   343                      }
   344                  );
   345              }
   346          ])
   347  
   348          // Provide File Upload progress feedback:
   349          .controller('FileUploadProgressController', [
   350              '$scope', '$attrs', '$parse',
   351              function ($scope, $attrs, $parse) {
   352                  var fn = $parse($attrs.fileUploadProgress),
   353                      update = function () {
   354                          var progress = fn($scope);
   355                          if (!progress || !progress.total) {
   356                              return;
   357                          }
   358                          $scope.num = Math.floor(
   359                              progress.loaded / progress.total * 100
   360                          );
   361                      };
   362                  update();
   363                  $scope.$watch(
   364                      $attrs.fileUploadProgress + '.loaded',
   365                      function (newValue, oldValue) {
   366                          if (newValue !== oldValue) {
   367                              update();
   368                          }
   369                      }
   370                  );
   371              }
   372          ])
   373  
   374          // Display File Upload previews:
   375          .controller('FileUploadPreviewController', [
   376              '$scope', '$element', '$attrs',
   377              function ($scope, $element, $attrs) {
   378                  $scope.$watch(
   379                      $attrs.fileUploadPreview + '.preview',
   380                      function (preview) {
   381                          $element.empty();
   382                          if (preview) {
   383                              $element.append(preview);
   384                          }
   385                      }
   386                  );
   387              }
   388          ])
   389  
   390          .directive('fileUpload', function () {
   391              return {
   392                  controller: 'FileUploadController',
   393                  scope: true
   394              };
   395          })
   396  
   397          .directive('fileUploadProgress', function () {
   398              return {
   399                  controller: 'FileUploadProgressController',
   400                  scope: true
   401              };
   402          })
   403  
   404          .directive('fileUploadPreview', function () {
   405              return {
   406                  controller: 'FileUploadPreviewController'
   407              };
   408          })
   409  
   410          // Enhance the HTML5 download attribute to
   411          // allow drag&drop of files to the desktop:
   412          .directive('download', function () {
   413              return function (scope, elm) {
   414                  elm.on('dragstart', function (e) {
   415                      try {
   416                          e.originalEvent.dataTransfer.setData(
   417                              'DownloadURL',
   418                              [
   419                                  'application/octet-stream',
   420                                  elm.prop('download'),
   421                                  elm.prop('href')
   422                              ].join(':')
   423                          );
   424                      } catch (ignore) {}
   425                  });
   426              };
   427          });
   428  
   429  }));