GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Code Duplication    Length = 501-501 lines in 3 locations

third-party/angularjs-modules-plugins/ng-file-upload-12.2.12/demo/src/main/webapp/js/ng-file-upload-all.js 1 location

@@ 1626-2126 (lines=501) @@
1623
1624
})();
1625
1626
ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', function (UploadDataUrl, $q, $timeout) {
1627
  var upload = UploadDataUrl;
1628
1629
  function globStringToRegex(str) {
1630
    var regexp = '', excludes = [];
1631
    if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {
1632
      regexp = str.substring(1, str.length - 1);
1633
    } else {
1634
      var split = str.split(',');
1635
      if (split.length > 1) {
1636
        for (var i = 0; i < split.length; i++) {
1637
          var r = globStringToRegex(split[i]);
1638
          if (r.regexp) {
1639
            regexp += '(' + r.regexp + ')';
1640
            if (i < split.length - 1) {
1641
              regexp += '|';
1642
            }
1643
          } else {
1644
            excludes = excludes.concat(r.excludes);
1645
          }
1646
        }
1647
      } else {
1648
        if (str.indexOf('!') === 0) {
1649
          excludes.push('^((?!' + globStringToRegex(str.substring(1)).regexp + ').)*$');
1650
        } else {
1651
          if (str.indexOf('.') === 0) {
1652
            str = '*' + str;
1653
          }
1654
          regexp = '^' + str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]', 'g'), '\\$&') + '$';
1655
          regexp = regexp.replace(/\\\*/g, '.*').replace(/\\\?/g, '.');
1656
        }
1657
      }
1658
    }
1659
    return {regexp: regexp, excludes: excludes};
1660
  }
1661
1662
  upload.validatePattern = function (file, val) {
1663
    if (!val) {
1664
      return true;
1665
    }
1666
    var pattern = globStringToRegex(val), valid = true;
1667
    if (pattern.regexp && pattern.regexp.length) {
1668
      var regexp = new RegExp(pattern.regexp, 'i');
1669
      valid = (file.type != null && regexp.test(file.type)) ||
1670
        (file.name != null && regexp.test(file.name));
1671
    }
1672
    var len = pattern.excludes.length;
1673
    while (len--) {
1674
      var exclude = new RegExp(pattern.excludes[len], 'i');
1675
      valid = valid && (file.type == null || exclude.test(file.type)) &&
1676
        (file.name == null || exclude.test(file.name));
1677
    }
1678
    return valid;
1679
  };
1680
1681
  upload.ratioToFloat = function (val) {
1682
    var r = val.toString(), xIndex = r.search(/[x:]/i);
1683
    if (xIndex > -1) {
1684
      r = parseFloat(r.substring(0, xIndex)) / parseFloat(r.substring(xIndex + 1));
1685
    } else {
1686
      r = parseFloat(r);
1687
    }
1688
    return r;
1689
  };
1690
1691
  upload.registerModelChangeValidator = function (ngModel, attr, scope) {
1692
    if (ngModel) {
1693
      ngModel.$formatters.push(function (files) {
1694
        if (ngModel.$dirty) {
1695
          var filesArray = files;
1696
          if (files && !angular.isArray(files)) {
1697
            filesArray = [files];
1698
          }
1699
          upload.validate(filesArray, 0, ngModel, attr, scope).then(function () {
1700
            upload.applyModelValidation(ngModel, filesArray);
1701
          });
1702
        }
1703
        return files;
1704
      });
1705
    }
1706
  };
1707
1708
  function markModelAsDirty(ngModel, files) {
1709
    if (files != null && !ngModel.$dirty) {
1710
      if (ngModel.$setDirty) {
1711
        ngModel.$setDirty();
1712
      } else {
1713
        ngModel.$dirty = true;
1714
      }
1715
    }
1716
  }
1717
1718
  upload.applyModelValidation = function (ngModel, files) {
1719
    markModelAsDirty(ngModel, files);
1720
    angular.forEach(ngModel.$ngfValidations, function (validation) {
1721
      ngModel.$setValidity(validation.name, validation.valid);
1722
    });
1723
  };
1724
1725
  upload.getValidationAttr = function (attr, scope, name, validationName, file) {
1726
    var dName = 'ngf' + name[0].toUpperCase() + name.substr(1);
1727
    var val = upload.attrGetter(dName, attr, scope, {$file: file});
1728
    if (val == null) {
1729
      val = upload.attrGetter('ngfValidate', attr, scope, {$file: file});
1730
      if (val) {
1731
        var split = (validationName || name).split('.');
1732
        val = val[split[0]];
1733
        if (split.length > 1) {
1734
          val = val && val[split[1]];
1735
        }
1736
      }
1737
    }
1738
    return val;
1739
  };
1740
1741
  upload.validate = function (files, prevLength, ngModel, attr, scope) {
1742
    ngModel = ngModel || {};
1743
    ngModel.$ngfValidations = ngModel.$ngfValidations || [];
1744
1745
    angular.forEach(ngModel.$ngfValidations, function (v) {
1746
      v.valid = true;
1747
    });
1748
1749
    var attrGetter = function (name, params) {
1750
      return upload.attrGetter(name, attr, scope, params);
1751
    };
1752
1753
    var ignoredErrors = (upload.attrGetter('ngfIgnoreInvalid', attr, scope) || '').split(' ');
1754
    var runAllValidation = upload.attrGetter('ngfRunAllValidations', attr, scope);
1755
1756
    if (files == null || files.length === 0) {
1757
      return upload.emptyPromise({'validFiles': files, 'invalidFiles': []});
1758
    }
1759
1760
    files = files.length === undefined ? [files] : files.slice(0);
1761
    var invalidFiles = [];
1762
1763
    function validateSync(name, validationName, fn) {
1764
      if (files) {
1765
        var i = files.length, valid = null;
1766
        while (i--) {
1767
          var file = files[i];
1768
          if (file) {
1769
            var val = upload.getValidationAttr(attr, scope, name, validationName, file);
1770
            if (val != null) {
1771
              if (!fn(file, val, i)) {
1772
                if (ignoredErrors.indexOf(name) === -1) {
1773
                  file.$error = name;
1774
                  (file.$errorMessages = (file.$errorMessages || {}))[name] = true;
1775
                  file.$errorParam = val;
1776
                  if (invalidFiles.indexOf(file) === -1) {
1777
                    invalidFiles.push(file);
1778
                  }
1779
                  if (!runAllValidation) {
1780
                    files.splice(i, 1);
1781
                  }
1782
                  valid = false;
1783
                } else {
1784
                  files.splice(i, 1);
1785
                }
1786
              }
1787
            }
1788
          }
1789
        }
1790
        if (valid !== null) {
1791
          ngModel.$ngfValidations.push({name: name, valid: valid});
1792
        }
1793
      }
1794
    }
1795
1796
    validateSync('pattern', null, upload.validatePattern);
1797
    validateSync('minSize', 'size.min', function (file, val) {
1798
      return file.size + 0.1 >= upload.translateScalars(val);
1799
    });
1800
    validateSync('maxSize', 'size.max', function (file, val) {
1801
      return file.size - 0.1 <= upload.translateScalars(val);
1802
    });
1803
    var totalSize = 0;
1804
    validateSync('maxTotalSize', null, function (file, val) {
1805
      totalSize += file.size;
1806
      if (totalSize > upload.translateScalars(val)) {
1807
        files.splice(0, files.length);
1808
        return false;
1809
      }
1810
      return true;
1811
    });
1812
1813
    validateSync('validateFn', null, function (file, r) {
1814
      return r === true || r === null || r === '';
1815
    });
1816
1817
    if (!files.length) {
1818
      return upload.emptyPromise({'validFiles': [], 'invalidFiles': invalidFiles});
1819
    }
1820
1821
    function validateAsync(name, validationName, type, asyncFn, fn) {
1822
      function resolveResult(defer, file, val) {
1823
        function resolveInternal(fn) {
1824
          if (fn()) {
1825
            if (ignoredErrors.indexOf(name) === -1) {
1826
              file.$error = name;
1827
              (file.$errorMessages = (file.$errorMessages || {}))[name] = true;
1828
              file.$errorParam = val;
1829
              if (invalidFiles.indexOf(file) === -1) {
1830
                invalidFiles.push(file);
1831
              }
1832
              if (!runAllValidation) {
1833
                var i = files.indexOf(file);
1834
                if (i > -1) files.splice(i, 1);
1835
              }
1836
              defer.resolve(false);
1837
            } else {
1838
              var j = files.indexOf(file);
1839
              if (j > -1) files.splice(j, 1);
1840
              defer.resolve(true);
1841
            }
1842
          } else {
1843
            defer.resolve(true);
1844
          }
1845
        }
1846
1847
        if (val != null) {
1848
          asyncFn(file, val).then(function (d) {
1849
            resolveInternal(function () {
1850
              return !fn(d, val);
1851
            });
1852
          }, function () {
1853
            resolveInternal(function () {
1854
              return attrGetter('ngfValidateForce', {$file: file});
1855
            });
1856
          });
1857
        } else {
1858
          defer.resolve(true);
1859
        }
1860
      }
1861
1862
      var promises = [upload.emptyPromise(true)];
1863
      if (files) {
1864
        files = files.length === undefined ? [files] : files;
1865
        angular.forEach(files, function (file) {
1866
          var defer = $q.defer();
1867
          promises.push(defer.promise);
1868
          if (type && (file.type == null || file.type.search(type) !== 0)) {
1869
            defer.resolve(true);
1870
            return;
1871
          }
1872
          if (name === 'dimensions' && upload.attrGetter('ngfDimensions', attr) != null) {
1873
            upload.imageDimensions(file).then(function (d) {
1874
              resolveResult(defer, file,
1875
                attrGetter('ngfDimensions', {$file: file, $width: d.width, $height: d.height}));
1876
            }, function () {
1877
              defer.resolve(false);
1878
            });
1879
          } else if (name === 'duration' && upload.attrGetter('ngfDuration', attr) != null) {
1880
            upload.mediaDuration(file).then(function (d) {
1881
              resolveResult(defer, file,
1882
                attrGetter('ngfDuration', {$file: file, $duration: d}));
1883
            }, function () {
1884
              defer.resolve(false);
1885
            });
1886
          } else {
1887
            resolveResult(defer, file,
1888
              upload.getValidationAttr(attr, scope, name, validationName, file));
1889
          }
1890
        });
1891
      }
1892
      var deffer = $q.defer();
1893
      $q.all(promises).then(function (values) {
1894
        var isValid = true;
1895
        for (var i = 0; i < values.length; i++) {
1896
          if (!values[i]) {
1897
            isValid = false;
1898
            break;
1899
          }
1900
        }
1901
        ngModel.$ngfValidations.push({name: name, valid: isValid});
1902
        deffer.resolve(isValid);
1903
      });
1904
      return deffer.promise;
1905
    }
1906
1907
    var deffer = $q.defer();
1908
    var promises = [];
1909
1910
    promises.push(validateAsync('maxHeight', 'height.max', /image/,
1911
      this.imageDimensions, function (d, val) {
1912
        return d.height <= val;
1913
      }));
1914
    promises.push(validateAsync('minHeight', 'height.min', /image/,
1915
      this.imageDimensions, function (d, val) {
1916
        return d.height >= val;
1917
      }));
1918
    promises.push(validateAsync('maxWidth', 'width.max', /image/,
1919
      this.imageDimensions, function (d, val) {
1920
        return d.width <= val;
1921
      }));
1922
    promises.push(validateAsync('minWidth', 'width.min', /image/,
1923
      this.imageDimensions, function (d, val) {
1924
        return d.width >= val;
1925
      }));
1926
    promises.push(validateAsync('dimensions', null, /image/,
1927
      function (file, val) {
1928
        return upload.emptyPromise(val);
1929
      }, function (r) {
1930
        return r;
1931
      }));
1932
    promises.push(validateAsync('ratio', null, /image/,
1933
      this.imageDimensions, function (d, val) {
1934
        var split = val.toString().split(','), valid = false;
1935
        for (var i = 0; i < split.length; i++) {
1936
          if (Math.abs((d.width / d.height) - upload.ratioToFloat(split[i])) < 0.01) {
1937
            valid = true;
1938
          }
1939
        }
1940
        return valid;
1941
      }));
1942
    promises.push(validateAsync('maxRatio', 'ratio.max', /image/,
1943
      this.imageDimensions, function (d, val) {
1944
        return (d.width / d.height) - upload.ratioToFloat(val) < 0.0001;
1945
      }));
1946
    promises.push(validateAsync('minRatio', 'ratio.min', /image/,
1947
      this.imageDimensions, function (d, val) {
1948
        return (d.width / d.height) - upload.ratioToFloat(val) > -0.0001;
1949
      }));
1950
    promises.push(validateAsync('maxDuration', 'duration.max', /audio|video/,
1951
      this.mediaDuration, function (d, val) {
1952
        return d <= upload.translateScalars(val);
1953
      }));
1954
    promises.push(validateAsync('minDuration', 'duration.min', /audio|video/,
1955
      this.mediaDuration, function (d, val) {
1956
        return d >= upload.translateScalars(val);
1957
      }));
1958
    promises.push(validateAsync('duration', null, /audio|video/,
1959
      function (file, val) {
1960
        return upload.emptyPromise(val);
1961
      }, function (r) {
1962
        return r;
1963
      }));
1964
1965
    promises.push(validateAsync('validateAsyncFn', null, null,
1966
      function (file, val) {
1967
        return val;
1968
      }, function (r) {
1969
        return r === true || r === null || r === '';
1970
      }));
1971
1972
    $q.all(promises).then(function () {
1973
1974
      if (runAllValidation) {
1975
        for (var i = 0; i < files.length; i++) {
1976
          var file = files[i];
1977
          if (file.$error) {
1978
            files.splice(i--, 1);
1979
          }
1980
        }
1981
      }
1982
1983
      runAllValidation = false;
1984
      validateSync('maxFiles', null, function (file, val, i) {
1985
        return prevLength + i < val;
1986
      });
1987
1988
      deffer.resolve({'validFiles': files, 'invalidFiles': invalidFiles});
1989
    });
1990
    return deffer.promise;
1991
  };
1992
1993
  upload.imageDimensions = function (file) {
1994
    if (file.$ngfWidth && file.$ngfHeight) {
1995
      var d = $q.defer();
1996
      $timeout(function () {
1997
        d.resolve({width: file.$ngfWidth, height: file.$ngfHeight});
1998
      });
1999
      return d.promise;
2000
    }
2001
    if (file.$ngfDimensionPromise) return file.$ngfDimensionPromise;
2002
2003
    var deferred = $q.defer();
2004
    $timeout(function () {
2005
      if (file.type.indexOf('image') !== 0) {
2006
        deferred.reject('not image');
2007
        return;
2008
      }
2009
      upload.dataUrl(file).then(function (dataUrl) {
2010
        var img = angular.element('<img>').attr('src', dataUrl)
2011
          .css('visibility', 'hidden').css('position', 'fixed')
2012
          .css('max-width', 'none !important').css('max-height', 'none !important');
2013
2014
        function success() {
2015
          var width = img[0].naturalWidth || img[0].clientWidth;
2016
          var height = img[0].naturalHeight || img[0].clientHeight;
2017
          img.remove();
2018
          file.$ngfWidth = width;
2019
          file.$ngfHeight = height;
2020
          deferred.resolve({width: width, height: height});
2021
        }
2022
2023
        function error() {
2024
          img.remove();
2025
          deferred.reject('load error');
2026
        }
2027
2028
        img.on('load', success);
2029
        img.on('error', error);
2030
2031
        var secondsCounter = 0;
2032
        function checkLoadErrorInCaseOfNoCallback() {
2033
          $timeout(function () {
2034
            if (img[0].parentNode) {
2035
              if (img[0].clientWidth) {
2036
                success();
2037
              } else if (secondsCounter++ > 10) {
2038
                error();
2039
              } else {
2040
                checkLoadErrorInCaseOfNoCallback();
2041
              }
2042
            }
2043
          }, 1000);
2044
        }
2045
2046
        checkLoadErrorInCaseOfNoCallback();
2047
2048
        angular.element(document.getElementsByTagName('body')[0]).append(img);
2049
      }, function () {
2050
        deferred.reject('load error');
2051
      });
2052
    });
2053
2054
    file.$ngfDimensionPromise = deferred.promise;
2055
    file.$ngfDimensionPromise['finally'](function () {
2056
      delete file.$ngfDimensionPromise;
2057
    });
2058
    return file.$ngfDimensionPromise;
2059
  };
2060
2061
  upload.mediaDuration = function (file) {
2062
    if (file.$ngfDuration) {
2063
      var d = $q.defer();
2064
      $timeout(function () {
2065
        d.resolve(file.$ngfDuration);
2066
      });
2067
      return d.promise;
2068
    }
2069
    if (file.$ngfDurationPromise) return file.$ngfDurationPromise;
2070
2071
    var deferred = $q.defer();
2072
    $timeout(function () {
2073
      if (file.type.indexOf('audio') !== 0 && file.type.indexOf('video') !== 0) {
2074
        deferred.reject('not media');
2075
        return;
2076
      }
2077
      upload.dataUrl(file).then(function (dataUrl) {
2078
        var el = angular.element(file.type.indexOf('audio') === 0 ? '<audio>' : '<video>')
2079
          .attr('src', dataUrl).css('visibility', 'none').css('position', 'fixed');
2080
2081
        function success() {
2082
          var duration = el[0].duration;
2083
          file.$ngfDuration = duration;
2084
          el.remove();
2085
          deferred.resolve(duration);
2086
        }
2087
2088
        function error() {
2089
          el.remove();
2090
          deferred.reject('load error');
2091
        }
2092
2093
        el.on('loadedmetadata', success);
2094
        el.on('error', error);
2095
        var count = 0;
2096
2097
        function checkLoadError() {
2098
          $timeout(function () {
2099
            if (el[0].parentNode) {
2100
              if (el[0].duration) {
2101
                success();
2102
              } else if (count > 10) {
2103
                error();
2104
              } else {
2105
                checkLoadError();
2106
              }
2107
            }
2108
          }, 1000);
2109
        }
2110
2111
        checkLoadError();
2112
2113
        angular.element(document.body).append(el);
2114
      }, function () {
2115
        deferred.reject('load error');
2116
      });
2117
    });
2118
2119
    file.$ngfDurationPromise = deferred.promise;
2120
    file.$ngfDurationPromise['finally'](function () {
2121
      delete file.$ngfDurationPromise;
2122
    });
2123
    return file.$ngfDurationPromise;
2124
  };
2125
  return upload;
2126
}
2127
]);
2128
2129
ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadValidate, $q) {

third-party/angularjs-modules-plugins/ng-file-upload-12.2.12/demo/src/main/webapp/js/ng-file-upload.js 1 location

@@ 1204-1704 (lines=501) @@
1201
1202
})();
1203
1204
ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', function (UploadDataUrl, $q, $timeout) {
1205
  var upload = UploadDataUrl;
1206
1207
  function globStringToRegex(str) {
1208
    var regexp = '', excludes = [];
1209
    if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {
1210
      regexp = str.substring(1, str.length - 1);
1211
    } else {
1212
      var split = str.split(',');
1213
      if (split.length > 1) {
1214
        for (var i = 0; i < split.length; i++) {
1215
          var r = globStringToRegex(split[i]);
1216
          if (r.regexp) {
1217
            regexp += '(' + r.regexp + ')';
1218
            if (i < split.length - 1) {
1219
              regexp += '|';
1220
            }
1221
          } else {
1222
            excludes = excludes.concat(r.excludes);
1223
          }
1224
        }
1225
      } else {
1226
        if (str.indexOf('!') === 0) {
1227
          excludes.push('^((?!' + globStringToRegex(str.substring(1)).regexp + ').)*$');
1228
        } else {
1229
          if (str.indexOf('.') === 0) {
1230
            str = '*' + str;
1231
          }
1232
          regexp = '^' + str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]', 'g'), '\\$&') + '$';
1233
          regexp = regexp.replace(/\\\*/g, '.*').replace(/\\\?/g, '.');
1234
        }
1235
      }
1236
    }
1237
    return {regexp: regexp, excludes: excludes};
1238
  }
1239
1240
  upload.validatePattern = function (file, val) {
1241
    if (!val) {
1242
      return true;
1243
    }
1244
    var pattern = globStringToRegex(val), valid = true;
1245
    if (pattern.regexp && pattern.regexp.length) {
1246
      var regexp = new RegExp(pattern.regexp, 'i');
1247
      valid = (file.type != null && regexp.test(file.type)) ||
1248
        (file.name != null && regexp.test(file.name));
1249
    }
1250
    var len = pattern.excludes.length;
1251
    while (len--) {
1252
      var exclude = new RegExp(pattern.excludes[len], 'i');
1253
      valid = valid && (file.type == null || exclude.test(file.type)) &&
1254
        (file.name == null || exclude.test(file.name));
1255
    }
1256
    return valid;
1257
  };
1258
1259
  upload.ratioToFloat = function (val) {
1260
    var r = val.toString(), xIndex = r.search(/[x:]/i);
1261
    if (xIndex > -1) {
1262
      r = parseFloat(r.substring(0, xIndex)) / parseFloat(r.substring(xIndex + 1));
1263
    } else {
1264
      r = parseFloat(r);
1265
    }
1266
    return r;
1267
  };
1268
1269
  upload.registerModelChangeValidator = function (ngModel, attr, scope) {
1270
    if (ngModel) {
1271
      ngModel.$formatters.push(function (files) {
1272
        if (ngModel.$dirty) {
1273
          var filesArray = files;
1274
          if (files && !angular.isArray(files)) {
1275
            filesArray = [files];
1276
          }
1277
          upload.validate(filesArray, 0, ngModel, attr, scope).then(function () {
1278
            upload.applyModelValidation(ngModel, filesArray);
1279
          });
1280
        }
1281
        return files;
1282
      });
1283
    }
1284
  };
1285
1286
  function markModelAsDirty(ngModel, files) {
1287
    if (files != null && !ngModel.$dirty) {
1288
      if (ngModel.$setDirty) {
1289
        ngModel.$setDirty();
1290
      } else {
1291
        ngModel.$dirty = true;
1292
      }
1293
    }
1294
  }
1295
1296
  upload.applyModelValidation = function (ngModel, files) {
1297
    markModelAsDirty(ngModel, files);
1298
    angular.forEach(ngModel.$ngfValidations, function (validation) {
1299
      ngModel.$setValidity(validation.name, validation.valid);
1300
    });
1301
  };
1302
1303
  upload.getValidationAttr = function (attr, scope, name, validationName, file) {
1304
    var dName = 'ngf' + name[0].toUpperCase() + name.substr(1);
1305
    var val = upload.attrGetter(dName, attr, scope, {$file: file});
1306
    if (val == null) {
1307
      val = upload.attrGetter('ngfValidate', attr, scope, {$file: file});
1308
      if (val) {
1309
        var split = (validationName || name).split('.');
1310
        val = val[split[0]];
1311
        if (split.length > 1) {
1312
          val = val && val[split[1]];
1313
        }
1314
      }
1315
    }
1316
    return val;
1317
  };
1318
1319
  upload.validate = function (files, prevLength, ngModel, attr, scope) {
1320
    ngModel = ngModel || {};
1321
    ngModel.$ngfValidations = ngModel.$ngfValidations || [];
1322
1323
    angular.forEach(ngModel.$ngfValidations, function (v) {
1324
      v.valid = true;
1325
    });
1326
1327
    var attrGetter = function (name, params) {
1328
      return upload.attrGetter(name, attr, scope, params);
1329
    };
1330
1331
    var ignoredErrors = (upload.attrGetter('ngfIgnoreInvalid', attr, scope) || '').split(' ');
1332
    var runAllValidation = upload.attrGetter('ngfRunAllValidations', attr, scope);
1333
1334
    if (files == null || files.length === 0) {
1335
      return upload.emptyPromise({'validFiles': files, 'invalidFiles': []});
1336
    }
1337
1338
    files = files.length === undefined ? [files] : files.slice(0);
1339
    var invalidFiles = [];
1340
1341
    function validateSync(name, validationName, fn) {
1342
      if (files) {
1343
        var i = files.length, valid = null;
1344
        while (i--) {
1345
          var file = files[i];
1346
          if (file) {
1347
            var val = upload.getValidationAttr(attr, scope, name, validationName, file);
1348
            if (val != null) {
1349
              if (!fn(file, val, i)) {
1350
                if (ignoredErrors.indexOf(name) === -1) {
1351
                  file.$error = name;
1352
                  (file.$errorMessages = (file.$errorMessages || {}))[name] = true;
1353
                  file.$errorParam = val;
1354
                  if (invalidFiles.indexOf(file) === -1) {
1355
                    invalidFiles.push(file);
1356
                  }
1357
                  if (!runAllValidation) {
1358
                    files.splice(i, 1);
1359
                  }
1360
                  valid = false;
1361
                } else {
1362
                  files.splice(i, 1);
1363
                }
1364
              }
1365
            }
1366
          }
1367
        }
1368
        if (valid !== null) {
1369
          ngModel.$ngfValidations.push({name: name, valid: valid});
1370
        }
1371
      }
1372
    }
1373
1374
    validateSync('pattern', null, upload.validatePattern);
1375
    validateSync('minSize', 'size.min', function (file, val) {
1376
      return file.size + 0.1 >= upload.translateScalars(val);
1377
    });
1378
    validateSync('maxSize', 'size.max', function (file, val) {
1379
      return file.size - 0.1 <= upload.translateScalars(val);
1380
    });
1381
    var totalSize = 0;
1382
    validateSync('maxTotalSize', null, function (file, val) {
1383
      totalSize += file.size;
1384
      if (totalSize > upload.translateScalars(val)) {
1385
        files.splice(0, files.length);
1386
        return false;
1387
      }
1388
      return true;
1389
    });
1390
1391
    validateSync('validateFn', null, function (file, r) {
1392
      return r === true || r === null || r === '';
1393
    });
1394
1395
    if (!files.length) {
1396
      return upload.emptyPromise({'validFiles': [], 'invalidFiles': invalidFiles});
1397
    }
1398
1399
    function validateAsync(name, validationName, type, asyncFn, fn) {
1400
      function resolveResult(defer, file, val) {
1401
        function resolveInternal(fn) {
1402
          if (fn()) {
1403
            if (ignoredErrors.indexOf(name) === -1) {
1404
              file.$error = name;
1405
              (file.$errorMessages = (file.$errorMessages || {}))[name] = true;
1406
              file.$errorParam = val;
1407
              if (invalidFiles.indexOf(file) === -1) {
1408
                invalidFiles.push(file);
1409
              }
1410
              if (!runAllValidation) {
1411
                var i = files.indexOf(file);
1412
                if (i > -1) files.splice(i, 1);
1413
              }
1414
              defer.resolve(false);
1415
            } else {
1416
              var j = files.indexOf(file);
1417
              if (j > -1) files.splice(j, 1);
1418
              defer.resolve(true);
1419
            }
1420
          } else {
1421
            defer.resolve(true);
1422
          }
1423
        }
1424
1425
        if (val != null) {
1426
          asyncFn(file, val).then(function (d) {
1427
            resolveInternal(function () {
1428
              return !fn(d, val);
1429
            });
1430
          }, function () {
1431
            resolveInternal(function () {
1432
              return attrGetter('ngfValidateForce', {$file: file});
1433
            });
1434
          });
1435
        } else {
1436
          defer.resolve(true);
1437
        }
1438
      }
1439
1440
      var promises = [upload.emptyPromise(true)];
1441
      if (files) {
1442
        files = files.length === undefined ? [files] : files;
1443
        angular.forEach(files, function (file) {
1444
          var defer = $q.defer();
1445
          promises.push(defer.promise);
1446
          if (type && (file.type == null || file.type.search(type) !== 0)) {
1447
            defer.resolve(true);
1448
            return;
1449
          }
1450
          if (name === 'dimensions' && upload.attrGetter('ngfDimensions', attr) != null) {
1451
            upload.imageDimensions(file).then(function (d) {
1452
              resolveResult(defer, file,
1453
                attrGetter('ngfDimensions', {$file: file, $width: d.width, $height: d.height}));
1454
            }, function () {
1455
              defer.resolve(false);
1456
            });
1457
          } else if (name === 'duration' && upload.attrGetter('ngfDuration', attr) != null) {
1458
            upload.mediaDuration(file).then(function (d) {
1459
              resolveResult(defer, file,
1460
                attrGetter('ngfDuration', {$file: file, $duration: d}));
1461
            }, function () {
1462
              defer.resolve(false);
1463
            });
1464
          } else {
1465
            resolveResult(defer, file,
1466
              upload.getValidationAttr(attr, scope, name, validationName, file));
1467
          }
1468
        });
1469
      }
1470
      var deffer = $q.defer();
1471
      $q.all(promises).then(function (values) {
1472
        var isValid = true;
1473
        for (var i = 0; i < values.length; i++) {
1474
          if (!values[i]) {
1475
            isValid = false;
1476
            break;
1477
          }
1478
        }
1479
        ngModel.$ngfValidations.push({name: name, valid: isValid});
1480
        deffer.resolve(isValid);
1481
      });
1482
      return deffer.promise;
1483
    }
1484
1485
    var deffer = $q.defer();
1486
    var promises = [];
1487
1488
    promises.push(validateAsync('maxHeight', 'height.max', /image/,
1489
      this.imageDimensions, function (d, val) {
1490
        return d.height <= val;
1491
      }));
1492
    promises.push(validateAsync('minHeight', 'height.min', /image/,
1493
      this.imageDimensions, function (d, val) {
1494
        return d.height >= val;
1495
      }));
1496
    promises.push(validateAsync('maxWidth', 'width.max', /image/,
1497
      this.imageDimensions, function (d, val) {
1498
        return d.width <= val;
1499
      }));
1500
    promises.push(validateAsync('minWidth', 'width.min', /image/,
1501
      this.imageDimensions, function (d, val) {
1502
        return d.width >= val;
1503
      }));
1504
    promises.push(validateAsync('dimensions', null, /image/,
1505
      function (file, val) {
1506
        return upload.emptyPromise(val);
1507
      }, function (r) {
1508
        return r;
1509
      }));
1510
    promises.push(validateAsync('ratio', null, /image/,
1511
      this.imageDimensions, function (d, val) {
1512
        var split = val.toString().split(','), valid = false;
1513
        for (var i = 0; i < split.length; i++) {
1514
          if (Math.abs((d.width / d.height) - upload.ratioToFloat(split[i])) < 0.01) {
1515
            valid = true;
1516
          }
1517
        }
1518
        return valid;
1519
      }));
1520
    promises.push(validateAsync('maxRatio', 'ratio.max', /image/,
1521
      this.imageDimensions, function (d, val) {
1522
        return (d.width / d.height) - upload.ratioToFloat(val) < 0.0001;
1523
      }));
1524
    promises.push(validateAsync('minRatio', 'ratio.min', /image/,
1525
      this.imageDimensions, function (d, val) {
1526
        return (d.width / d.height) - upload.ratioToFloat(val) > -0.0001;
1527
      }));
1528
    promises.push(validateAsync('maxDuration', 'duration.max', /audio|video/,
1529
      this.mediaDuration, function (d, val) {
1530
        return d <= upload.translateScalars(val);
1531
      }));
1532
    promises.push(validateAsync('minDuration', 'duration.min', /audio|video/,
1533
      this.mediaDuration, function (d, val) {
1534
        return d >= upload.translateScalars(val);
1535
      }));
1536
    promises.push(validateAsync('duration', null, /audio|video/,
1537
      function (file, val) {
1538
        return upload.emptyPromise(val);
1539
      }, function (r) {
1540
        return r;
1541
      }));
1542
1543
    promises.push(validateAsync('validateAsyncFn', null, null,
1544
      function (file, val) {
1545
        return val;
1546
      }, function (r) {
1547
        return r === true || r === null || r === '';
1548
      }));
1549
1550
    $q.all(promises).then(function () {
1551
1552
      if (runAllValidation) {
1553
        for (var i = 0; i < files.length; i++) {
1554
          var file = files[i];
1555
          if (file.$error) {
1556
            files.splice(i--, 1);
1557
          }
1558
        }
1559
      }
1560
1561
      runAllValidation = false;
1562
      validateSync('maxFiles', null, function (file, val, i) {
1563
        return prevLength + i < val;
1564
      });
1565
1566
      deffer.resolve({'validFiles': files, 'invalidFiles': invalidFiles});
1567
    });
1568
    return deffer.promise;
1569
  };
1570
1571
  upload.imageDimensions = function (file) {
1572
    if (file.$ngfWidth && file.$ngfHeight) {
1573
      var d = $q.defer();
1574
      $timeout(function () {
1575
        d.resolve({width: file.$ngfWidth, height: file.$ngfHeight});
1576
      });
1577
      return d.promise;
1578
    }
1579
    if (file.$ngfDimensionPromise) return file.$ngfDimensionPromise;
1580
1581
    var deferred = $q.defer();
1582
    $timeout(function () {
1583
      if (file.type.indexOf('image') !== 0) {
1584
        deferred.reject('not image');
1585
        return;
1586
      }
1587
      upload.dataUrl(file).then(function (dataUrl) {
1588
        var img = angular.element('<img>').attr('src', dataUrl)
1589
          .css('visibility', 'hidden').css('position', 'fixed')
1590
          .css('max-width', 'none !important').css('max-height', 'none !important');
1591
1592
        function success() {
1593
          var width = img[0].naturalWidth || img[0].clientWidth;
1594
          var height = img[0].naturalHeight || img[0].clientHeight;
1595
          img.remove();
1596
          file.$ngfWidth = width;
1597
          file.$ngfHeight = height;
1598
          deferred.resolve({width: width, height: height});
1599
        }
1600
1601
        function error() {
1602
          img.remove();
1603
          deferred.reject('load error');
1604
        }
1605
1606
        img.on('load', success);
1607
        img.on('error', error);
1608
1609
        var secondsCounter = 0;
1610
        function checkLoadErrorInCaseOfNoCallback() {
1611
          $timeout(function () {
1612
            if (img[0].parentNode) {
1613
              if (img[0].clientWidth) {
1614
                success();
1615
              } else if (secondsCounter++ > 10) {
1616
                error();
1617
              } else {
1618
                checkLoadErrorInCaseOfNoCallback();
1619
              }
1620
            }
1621
          }, 1000);
1622
        }
1623
1624
        checkLoadErrorInCaseOfNoCallback();
1625
1626
        angular.element(document.getElementsByTagName('body')[0]).append(img);
1627
      }, function () {
1628
        deferred.reject('load error');
1629
      });
1630
    });
1631
1632
    file.$ngfDimensionPromise = deferred.promise;
1633
    file.$ngfDimensionPromise['finally'](function () {
1634
      delete file.$ngfDimensionPromise;
1635
    });
1636
    return file.$ngfDimensionPromise;
1637
  };
1638
1639
  upload.mediaDuration = function (file) {
1640
    if (file.$ngfDuration) {
1641
      var d = $q.defer();
1642
      $timeout(function () {
1643
        d.resolve(file.$ngfDuration);
1644
      });
1645
      return d.promise;
1646
    }
1647
    if (file.$ngfDurationPromise) return file.$ngfDurationPromise;
1648
1649
    var deferred = $q.defer();
1650
    $timeout(function () {
1651
      if (file.type.indexOf('audio') !== 0 && file.type.indexOf('video') !== 0) {
1652
        deferred.reject('not media');
1653
        return;
1654
      }
1655
      upload.dataUrl(file).then(function (dataUrl) {
1656
        var el = angular.element(file.type.indexOf('audio') === 0 ? '<audio>' : '<video>')
1657
          .attr('src', dataUrl).css('visibility', 'none').css('position', 'fixed');
1658
1659
        function success() {
1660
          var duration = el[0].duration;
1661
          file.$ngfDuration = duration;
1662
          el.remove();
1663
          deferred.resolve(duration);
1664
        }
1665
1666
        function error() {
1667
          el.remove();
1668
          deferred.reject('load error');
1669
        }
1670
1671
        el.on('loadedmetadata', success);
1672
        el.on('error', error);
1673
        var count = 0;
1674
1675
        function checkLoadError() {
1676
          $timeout(function () {
1677
            if (el[0].parentNode) {
1678
              if (el[0].duration) {
1679
                success();
1680
              } else if (count > 10) {
1681
                error();
1682
              } else {
1683
                checkLoadError();
1684
              }
1685
            }
1686
          }, 1000);
1687
        }
1688
1689
        checkLoadError();
1690
1691
        angular.element(document.body).append(el);
1692
      }, function () {
1693
        deferred.reject('load error');
1694
      });
1695
    });
1696
1697
    file.$ngfDurationPromise = deferred.promise;
1698
    file.$ngfDurationPromise['finally'](function () {
1699
      delete file.$ngfDurationPromise;
1700
    });
1701
    return file.$ngfDurationPromise;
1702
  };
1703
  return upload;
1704
}
1705
]);
1706
1707
ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadValidate, $q) {

third-party/angularjs-modules-plugins/ng-file-upload-12.2.12/src/validate.js 1 location

@@ 1-501 (lines=501) @@
1
ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', function (UploadDataUrl, $q, $timeout) {
2
  var upload = UploadDataUrl;
3
4
  function globStringToRegex(str) {
5
    var regexp = '', excludes = [];
6
    if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {
7
      regexp = str.substring(1, str.length - 1);
8
    } else {
9
      var split = str.split(',');
10
      if (split.length > 1) {
11
        for (var i = 0; i < split.length; i++) {
12
          var r = globStringToRegex(split[i]);
13
          if (r.regexp) {
14
            regexp += '(' + r.regexp + ')';
15
            if (i < split.length - 1) {
16
              regexp += '|';
17
            }
18
          } else {
19
            excludes = excludes.concat(r.excludes);
20
          }
21
        }
22
      } else {
23
        if (str.indexOf('!') === 0) {
24
          excludes.push('^((?!' + globStringToRegex(str.substring(1)).regexp + ').)*$');
25
        } else {
26
          if (str.indexOf('.') === 0) {
27
            str = '*' + str;
28
          }
29
          regexp = '^' + str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]', 'g'), '\\$&') + '$';
30
          regexp = regexp.replace(/\\\*/g, '.*').replace(/\\\?/g, '.');
31
        }
32
      }
33
    }
34
    return {regexp: regexp, excludes: excludes};
35
  }
36
37
  upload.validatePattern = function (file, val) {
38
    if (!val) {
39
      return true;
40
    }
41
    var pattern = globStringToRegex(val), valid = true;
42
    if (pattern.regexp && pattern.regexp.length) {
43
      var regexp = new RegExp(pattern.regexp, 'i');
44
      valid = (file.type != null && regexp.test(file.type)) ||
45
        (file.name != null && regexp.test(file.name));
46
    }
47
    var len = pattern.excludes.length;
48
    while (len--) {
49
      var exclude = new RegExp(pattern.excludes[len], 'i');
50
      valid = valid && (file.type == null || exclude.test(file.type)) &&
51
        (file.name == null || exclude.test(file.name));
52
    }
53
    return valid;
54
  };
55
56
  upload.ratioToFloat = function (val) {
57
    var r = val.toString(), xIndex = r.search(/[x:]/i);
58
    if (xIndex > -1) {
59
      r = parseFloat(r.substring(0, xIndex)) / parseFloat(r.substring(xIndex + 1));
60
    } else {
61
      r = parseFloat(r);
62
    }
63
    return r;
64
  };
65
66
  upload.registerModelChangeValidator = function (ngModel, attr, scope) {
67
    if (ngModel) {
68
      ngModel.$formatters.push(function (files) {
69
        if (ngModel.$dirty) {
70
          var filesArray = files;
71
          if (files && !angular.isArray(files)) {
72
            filesArray = [files];
73
          }
74
          upload.validate(filesArray, 0, ngModel, attr, scope).then(function () {
75
            upload.applyModelValidation(ngModel, filesArray);
76
          });
77
        }
78
        return files;
79
      });
80
    }
81
  };
82
83
  function markModelAsDirty(ngModel, files) {
84
    if (files != null && !ngModel.$dirty) {
85
      if (ngModel.$setDirty) {
86
        ngModel.$setDirty();
87
      } else {
88
        ngModel.$dirty = true;
89
      }
90
    }
91
  }
92
93
  upload.applyModelValidation = function (ngModel, files) {
94
    markModelAsDirty(ngModel, files);
95
    angular.forEach(ngModel.$ngfValidations, function (validation) {
96
      ngModel.$setValidity(validation.name, validation.valid);
97
    });
98
  };
99
100
  upload.getValidationAttr = function (attr, scope, name, validationName, file) {
101
    var dName = 'ngf' + name[0].toUpperCase() + name.substr(1);
102
    var val = upload.attrGetter(dName, attr, scope, {$file: file});
103
    if (val == null) {
104
      val = upload.attrGetter('ngfValidate', attr, scope, {$file: file});
105
      if (val) {
106
        var split = (validationName || name).split('.');
107
        val = val[split[0]];
108
        if (split.length > 1) {
109
          val = val && val[split[1]];
110
        }
111
      }
112
    }
113
    return val;
114
  };
115
116
  upload.validate = function (files, prevLength, ngModel, attr, scope) {
117
    ngModel = ngModel || {};
118
    ngModel.$ngfValidations = ngModel.$ngfValidations || [];
119
120
    angular.forEach(ngModel.$ngfValidations, function (v) {
121
      v.valid = true;
122
    });
123
124
    var attrGetter = function (name, params) {
125
      return upload.attrGetter(name, attr, scope, params);
126
    };
127
128
    var ignoredErrors = (upload.attrGetter('ngfIgnoreInvalid', attr, scope) || '').split(' ');
129
    var runAllValidation = upload.attrGetter('ngfRunAllValidations', attr, scope);
130
131
    if (files == null || files.length === 0) {
132
      return upload.emptyPromise({'validFiles': files, 'invalidFiles': []});
133
    }
134
135
    files = files.length === undefined ? [files] : files.slice(0);
136
    var invalidFiles = [];
137
138
    function validateSync(name, validationName, fn) {
139
      if (files) {
140
        var i = files.length, valid = null;
141
        while (i--) {
142
          var file = files[i];
143
          if (file) {
144
            var val = upload.getValidationAttr(attr, scope, name, validationName, file);
145
            if (val != null) {
146
              if (!fn(file, val, i)) {
147
                if (ignoredErrors.indexOf(name) === -1) {
148
                  file.$error = name;
149
                  (file.$errorMessages = (file.$errorMessages || {}))[name] = true;
150
                  file.$errorParam = val;
151
                  if (invalidFiles.indexOf(file) === -1) {
152
                    invalidFiles.push(file);
153
                  }
154
                  if (!runAllValidation) {
155
                    files.splice(i, 1);
156
                  }
157
                  valid = false;
158
                } else {
159
                  files.splice(i, 1);
160
                }
161
              }
162
            }
163
          }
164
        }
165
        if (valid !== null) {
166
          ngModel.$ngfValidations.push({name: name, valid: valid});
167
        }
168
      }
169
    }
170
171
    validateSync('pattern', null, upload.validatePattern);
172
    validateSync('minSize', 'size.min', function (file, val) {
173
      return file.size + 0.1 >= upload.translateScalars(val);
174
    });
175
    validateSync('maxSize', 'size.max', function (file, val) {
176
      return file.size - 0.1 <= upload.translateScalars(val);
177
    });
178
    var totalSize = 0;
179
    validateSync('maxTotalSize', null, function (file, val) {
180
      totalSize += file.size;
181
      if (totalSize > upload.translateScalars(val)) {
182
        files.splice(0, files.length);
183
        return false;
184
      }
185
      return true;
186
    });
187
188
    validateSync('validateFn', null, function (file, r) {
189
      return r === true || r === null || r === '';
190
    });
191
192
    if (!files.length) {
193
      return upload.emptyPromise({'validFiles': [], 'invalidFiles': invalidFiles});
194
    }
195
196
    function validateAsync(name, validationName, type, asyncFn, fn) {
197
      function resolveResult(defer, file, val) {
198
        function resolveInternal(fn) {
199
          if (fn()) {
200
            if (ignoredErrors.indexOf(name) === -1) {
201
              file.$error = name;
202
              (file.$errorMessages = (file.$errorMessages || {}))[name] = true;
203
              file.$errorParam = val;
204
              if (invalidFiles.indexOf(file) === -1) {
205
                invalidFiles.push(file);
206
              }
207
              if (!runAllValidation) {
208
                var i = files.indexOf(file);
209
                if (i > -1) files.splice(i, 1);
210
              }
211
              defer.resolve(false);
212
            } else {
213
              var j = files.indexOf(file);
214
              if (j > -1) files.splice(j, 1);
215
              defer.resolve(true);
216
            }
217
          } else {
218
            defer.resolve(true);
219
          }
220
        }
221
222
        if (val != null) {
223
          asyncFn(file, val).then(function (d) {
224
            resolveInternal(function () {
225
              return !fn(d, val);
226
            });
227
          }, function () {
228
            resolveInternal(function () {
229
              return attrGetter('ngfValidateForce', {$file: file});
230
            });
231
          });
232
        } else {
233
          defer.resolve(true);
234
        }
235
      }
236
237
      var promises = [upload.emptyPromise(true)];
238
      if (files) {
239
        files = files.length === undefined ? [files] : files;
240
        angular.forEach(files, function (file) {
241
          var defer = $q.defer();
242
          promises.push(defer.promise);
243
          if (type && (file.type == null || file.type.search(type) !== 0)) {
244
            defer.resolve(true);
245
            return;
246
          }
247
          if (name === 'dimensions' && upload.attrGetter('ngfDimensions', attr) != null) {
248
            upload.imageDimensions(file).then(function (d) {
249
              resolveResult(defer, file,
250
                attrGetter('ngfDimensions', {$file: file, $width: d.width, $height: d.height}));
251
            }, function () {
252
              defer.resolve(false);
253
            });
254
          } else if (name === 'duration' && upload.attrGetter('ngfDuration', attr) != null) {
255
            upload.mediaDuration(file).then(function (d) {
256
              resolveResult(defer, file,
257
                attrGetter('ngfDuration', {$file: file, $duration: d}));
258
            }, function () {
259
              defer.resolve(false);
260
            });
261
          } else {
262
            resolveResult(defer, file,
263
              upload.getValidationAttr(attr, scope, name, validationName, file));
264
          }
265
        });
266
      }
267
      var deffer = $q.defer();
268
      $q.all(promises).then(function (values) {
269
        var isValid = true;
270
        for (var i = 0; i < values.length; i++) {
271
          if (!values[i]) {
272
            isValid = false;
273
            break;
274
          }
275
        }
276
        ngModel.$ngfValidations.push({name: name, valid: isValid});
277
        deffer.resolve(isValid);
278
      });
279
      return deffer.promise;
280
    }
281
282
    var deffer = $q.defer();
283
    var promises = [];
284
285
    promises.push(validateAsync('maxHeight', 'height.max', /image/,
286
      this.imageDimensions, function (d, val) {
287
        return d.height <= val;
288
      }));
289
    promises.push(validateAsync('minHeight', 'height.min', /image/,
290
      this.imageDimensions, function (d, val) {
291
        return d.height >= val;
292
      }));
293
    promises.push(validateAsync('maxWidth', 'width.max', /image/,
294
      this.imageDimensions, function (d, val) {
295
        return d.width <= val;
296
      }));
297
    promises.push(validateAsync('minWidth', 'width.min', /image/,
298
      this.imageDimensions, function (d, val) {
299
        return d.width >= val;
300
      }));
301
    promises.push(validateAsync('dimensions', null, /image/,
302
      function (file, val) {
303
        return upload.emptyPromise(val);
304
      }, function (r) {
305
        return r;
306
      }));
307
    promises.push(validateAsync('ratio', null, /image/,
308
      this.imageDimensions, function (d, val) {
309
        var split = val.toString().split(','), valid = false;
310
        for (var i = 0; i < split.length; i++) {
311
          if (Math.abs((d.width / d.height) - upload.ratioToFloat(split[i])) < 0.01) {
312
            valid = true;
313
          }
314
        }
315
        return valid;
316
      }));
317
    promises.push(validateAsync('maxRatio', 'ratio.max', /image/,
318
      this.imageDimensions, function (d, val) {
319
        return (d.width / d.height) - upload.ratioToFloat(val) < 0.0001;
320
      }));
321
    promises.push(validateAsync('minRatio', 'ratio.min', /image/,
322
      this.imageDimensions, function (d, val) {
323
        return (d.width / d.height) - upload.ratioToFloat(val) > -0.0001;
324
      }));
325
    promises.push(validateAsync('maxDuration', 'duration.max', /audio|video/,
326
      this.mediaDuration, function (d, val) {
327
        return d <= upload.translateScalars(val);
328
      }));
329
    promises.push(validateAsync('minDuration', 'duration.min', /audio|video/,
330
      this.mediaDuration, function (d, val) {
331
        return d >= upload.translateScalars(val);
332
      }));
333
    promises.push(validateAsync('duration', null, /audio|video/,
334
      function (file, val) {
335
        return upload.emptyPromise(val);
336
      }, function (r) {
337
        return r;
338
      }));
339
340
    promises.push(validateAsync('validateAsyncFn', null, null,
341
      function (file, val) {
342
        return val;
343
      }, function (r) {
344
        return r === true || r === null || r === '';
345
      }));
346
347
    $q.all(promises).then(function () {
348
349
      if (runAllValidation) {
350
        for (var i = 0; i < files.length; i++) {
351
          var file = files[i];
352
          if (file.$error) {
353
            files.splice(i--, 1);
354
          }
355
        }
356
      }
357
358
      runAllValidation = false;
359
      validateSync('maxFiles', null, function (file, val, i) {
360
        return prevLength + i < val;
361
      });
362
363
      deffer.resolve({'validFiles': files, 'invalidFiles': invalidFiles});
364
    });
365
    return deffer.promise;
366
  };
367
368
  upload.imageDimensions = function (file) {
369
    if (file.$ngfWidth && file.$ngfHeight) {
370
      var d = $q.defer();
371
      $timeout(function () {
372
        d.resolve({width: file.$ngfWidth, height: file.$ngfHeight});
373
      });
374
      return d.promise;
375
    }
376
    if (file.$ngfDimensionPromise) return file.$ngfDimensionPromise;
377
378
    var deferred = $q.defer();
379
    $timeout(function () {
380
      if (file.type.indexOf('image') !== 0) {
381
        deferred.reject('not image');
382
        return;
383
      }
384
      upload.dataUrl(file).then(function (dataUrl) {
385
        var img = angular.element('<img>').attr('src', dataUrl)
386
          .css('visibility', 'hidden').css('position', 'fixed')
387
          .css('max-width', 'none !important').css('max-height', 'none !important');
388
389
        function success() {
390
          var width = img[0].naturalWidth || img[0].clientWidth;
391
          var height = img[0].naturalHeight || img[0].clientHeight;
392
          img.remove();
393
          file.$ngfWidth = width;
394
          file.$ngfHeight = height;
395
          deferred.resolve({width: width, height: height});
396
        }
397
398
        function error() {
399
          img.remove();
400
          deferred.reject('load error');
401
        }
402
403
        img.on('load', success);
404
        img.on('error', error);
405
406
        var secondsCounter = 0;
407
        function checkLoadErrorInCaseOfNoCallback() {
408
          $timeout(function () {
409
            if (img[0].parentNode) {
410
              if (img[0].clientWidth) {
411
                success();
412
              } else if (secondsCounter++ > 10) {
413
                error();
414
              } else {
415
                checkLoadErrorInCaseOfNoCallback();
416
              }
417
            }
418
          }, 1000);
419
        }
420
421
        checkLoadErrorInCaseOfNoCallback();
422
423
        angular.element(document.getElementsByTagName('body')[0]).append(img);
424
      }, function () {
425
        deferred.reject('load error');
426
      });
427
    });
428
429
    file.$ngfDimensionPromise = deferred.promise;
430
    file.$ngfDimensionPromise['finally'](function () {
431
      delete file.$ngfDimensionPromise;
432
    });
433
    return file.$ngfDimensionPromise;
434
  };
435
436
  upload.mediaDuration = function (file) {
437
    if (file.$ngfDuration) {
438
      var d = $q.defer();
439
      $timeout(function () {
440
        d.resolve(file.$ngfDuration);
441
      });
442
      return d.promise;
443
    }
444
    if (file.$ngfDurationPromise) return file.$ngfDurationPromise;
445
446
    var deferred = $q.defer();
447
    $timeout(function () {
448
      if (file.type.indexOf('audio') !== 0 && file.type.indexOf('video') !== 0) {
449
        deferred.reject('not media');
450
        return;
451
      }
452
      upload.dataUrl(file).then(function (dataUrl) {
453
        var el = angular.element(file.type.indexOf('audio') === 0 ? '<audio>' : '<video>')
454
          .attr('src', dataUrl).css('visibility', 'none').css('position', 'fixed');
455
456
        function success() {
457
          var duration = el[0].duration;
458
          file.$ngfDuration = duration;
459
          el.remove();
460
          deferred.resolve(duration);
461
        }
462
463
        function error() {
464
          el.remove();
465
          deferred.reject('load error');
466
        }
467
468
        el.on('loadedmetadata', success);
469
        el.on('error', error);
470
        var count = 0;
471
472
        function checkLoadError() {
473
          $timeout(function () {
474
            if (el[0].parentNode) {
475
              if (el[0].duration) {
476
                success();
477
              } else if (count > 10) {
478
                error();
479
              } else {
480
                checkLoadError();
481
              }
482
            }
483
          }, 1000);
484
        }
485
486
        checkLoadError();
487
488
        angular.element(document.body).append(el);
489
      }, function () {
490
        deferred.reject('load error');
491
      });
492
    });
493
494
    file.$ngfDurationPromise = deferred.promise;
495
    file.$ngfDurationPromise['finally'](function () {
496
      delete file.$ngfDurationPromise;
497
    });
498
    return file.$ngfDurationPromise;
499
  };
500
  return upload;
501
}
502
]);
503