summaryrefslogtreecommitdiff
path: root/xstatic/pkg/angular_fileupload/data/ng-file-upload-all.js
diff options
context:
space:
mode:
Diffstat (limited to 'xstatic/pkg/angular_fileupload/data/ng-file-upload-all.js')
-rw-r--r--xstatic/pkg/angular_fileupload/data/ng-file-upload-all.js535
1 files changed, 316 insertions, 219 deletions
diff --git a/xstatic/pkg/angular_fileupload/data/ng-file-upload-all.js b/xstatic/pkg/angular_fileupload/data/ng-file-upload-all.js
index fca2e64..e342351 100644
--- a/xstatic/pkg/angular_fileupload/data/ng-file-upload-all.js
+++ b/xstatic/pkg/angular_fileupload/data/ng-file-upload-all.js
@@ -1,9 +1,9 @@
/**!
- * AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
+ * AngularJS file upload directives and services. Supports: file upload/drop/paste, resume, cancel/abort,
* progress, resize, thumbnail, preview, validation and CORS
* FileAPI Flash shim for old browsers not supporting FormData
* @author Danial <danial.farid@gmail.com>
- * @version 12.0.4
+ * @version 12.2.13
*/
(function () {
@@ -424,7 +424,7 @@ if (!window.FileReader) {
* AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
* progress, resize, thumbnail, preview, validation and CORS
* @author Danial <danial.farid@gmail.com>
- * @version 12.0.4
+ * @version 12.2.13
*/
if (window.XMLHttpRequest && !(window.FileAPI && FileAPI.shouldLoad)) {
@@ -445,7 +445,7 @@ if (window.XMLHttpRequest && !(window.FileAPI && FileAPI.shouldLoad)) {
var ngFileUpload = angular.module('ngFileUpload', []);
-ngFileUpload.version = '12.0.4';
+ngFileUpload.version = '12.2.13';
ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {
var upload = this;
@@ -512,10 +512,12 @@ ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http,
function uploadWithAngular() {
$http(config).then(function (r) {
if (resumeSupported && config._chunkSize && !config._finished && config._file) {
+ var fileSize = config._file && config._file.size || 0;
notifyProgress({
- loaded: config._end,
- total: config._file && config._file.size,
- config: config, type: 'progress'
+ loaded: Math.min(config._end, fileSize),
+ total: fileSize,
+ config: config,
+ type: 'progress'
}
);
upload.upload(config, true);
@@ -554,6 +556,9 @@ ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http,
} else if (config.resumeSize) {
config.resumeSize().then(function (size) {
config._start = size;
+ if (config._chunkSize) {
+ config._end = config._start + config._chunkSize;
+ }
uploadWithAngular();
}, function (e) {
throw e;
@@ -607,9 +612,11 @@ ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http,
};
upload.promisesCount++;
- promise['finally'](function () {
- upload.promisesCount--;
- });
+ if (promise['finally'] && promise['finally'] instanceof Function) {
+ promise['finally'](function () {
+ upload.promisesCount--;
+ });
+ }
return promise;
}
@@ -793,9 +800,11 @@ ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http,
var arrayBufferView = new Uint8Array(resp.data);
var type = resp.headers('content-type') || 'image/WebP';
var blob = new window.Blob([arrayBufferView], {type: type});
+ var matches = url.match(/.*\/(.+?)(\?.*)?$/);
+ if (matches.length > 1) {
+ blob.name = matches[1];
+ }
defer.resolve(blob);
- //var split = type.split('[/;]');
- //blob.name = url.substring(0, 150).replace(/\W+/g, '') + '.' + (split.length > 1 ? split[1] : 'jpg');
}, function (e) {
defer.reject(e);
});
@@ -843,7 +852,7 @@ ngFileUpload.service('Upload', ['$parse', '$timeout', '$compile', '$q', 'UploadE
};
upload.shouldUpdateOn = function (type, attr, scope) {
- var modelOptions = upload.attrGetter('ngModelOptions', attr, scope);
+ var modelOptions = upload.attrGetter('ngfModelOptions', attr, scope);
if (modelOptions && modelOptions.updateOn) {
return modelOptions.updateOn.split(' ').indexOf(type) > -1;
}
@@ -893,13 +902,13 @@ ngFileUpload.service('Upload', ['$parse', '$timeout', '$compile', '$q', 'UploadE
return $q.all(promises);
}
- function resize(files, attr, scope) {
+ function resizeFile(files, attr, scope, ngModel) {
var resizeVal = upload.attrGetter('ngfResize', attr, scope);
if (!resizeVal || !upload.isResizeSupported() || !files.length) return upload.emptyPromise();
if (resizeVal instanceof Function) {
var defer = $q.defer();
- resizeVal(files).then(function (p) {
- resizeWithParams(p, files, attr, scope).then(function (r) {
+ return resizeVal(files).then(function (p) {
+ resizeWithParams(p, files, attr, scope, ngModel).then(function (r) {
defer.resolve(r);
}, function (e) {
defer.reject(e);
@@ -908,27 +917,30 @@ ngFileUpload.service('Upload', ['$parse', '$timeout', '$compile', '$q', 'UploadE
defer.reject(e);
});
} else {
- return resizeWithParams(resizeVal, files, attr, scope);
+ return resizeWithParams(resizeVal, files, attr, scope, ngModel);
}
}
- function resizeWithParams(param, files, attr, scope) {
+ function resizeWithParams(params, files, attr, scope, ngModel) {
var promises = [upload.emptyPromise()];
function handleFile(f, i) {
if (f.type.indexOf('image') === 0) {
- if (param.pattern && !upload.validatePattern(f, param.pattern)) return;
- var promise = upload.resize(f, param.width, param.height, param.quality,
- param.type, param.ratio, param.centerCrop, function (width, height) {
- return upload.attrGetter('ngfResizeIf', attr, scope,
- {$width: width, $height: height, $file: f});
- }, param.restoreExif !== false);
+ if (params.pattern && !upload.validatePattern(f, params.pattern)) return;
+ params.resizeIf = function (width, height) {
+ return upload.attrGetter('ngfResizeIf', attr, scope,
+ {$width: width, $height: height, $file: f});
+ };
+ var promise = upload.resize(f, params);
promises.push(promise);
promise.then(function (resizedFile) {
files.splice(i, 1, resizedFile);
}, function (e) {
f.$error = 'resize';
+ (f.$errorMessages = (f.$errorMessages || {})).resize = true;
f.$errorParam = (e ? (e.message ? e.message : e) + ': ' : '') + (f && f.name);
+ ngModel.$ngfValidations.push({name: 'resize', valid: false});
+ upload.applyModelValidation(ngModel, files);
});
}
}
@@ -1015,18 +1027,6 @@ ngFileUpload.service('Upload', ['$parse', '$timeout', '$compile', '$q', 'UploadE
return angular.isArray(v) ? v : [v];
}
- function separateInvalids() {
- valids = [];
- invalids = [];
- angular.forEach(allNewFiles, function (file) {
- if (file.$error) {
- invalids.push(file);
- } else {
- valids.push(file);
- }
- });
- }
-
function resizeAndUpdate() {
function updateModel() {
$timeout(function () {
@@ -1036,17 +1036,30 @@ ngFileUpload.service('Upload', ['$parse', '$timeout', '$compile', '$q', 'UploadE
}, options && options.debounce ? options.debounce.change || options.debounce : 0);
}
- resize(validateAfterResize ? allNewFiles : valids, attr, scope).then(function () {
+ var resizingFiles = validateAfterResize ? allNewFiles : valids;
+ resizeFile(resizingFiles, attr, scope, ngModel).then(function () {
if (validateAfterResize) {
- upload.validate(allNewFiles, prevValidFiles.length, ngModel, attr, scope).then(function () {
- separateInvalids();
- updateModel();
- });
+ upload.validate(allNewFiles, keep ? prevValidFiles.length : 0, ngModel, attr, scope)
+ .then(function (validationResult) {
+ valids = validationResult.validsFiles;
+ invalids = validationResult.invalidsFiles;
+ updateModel();
+ });
} else {
updateModel();
}
- }, function (e) {
- throw 'Could not resize files ' + e;
+ }, function () {
+ for (var i = 0; i < resizingFiles.length; i++) {
+ var f = resizingFiles[i];
+ if (f.$error === 'resize') {
+ var index = valids.indexOf(f);
+ if (index > -1) {
+ valids.splice(index, 1);
+ invalids.push(f);
+ }
+ updateModel();
+ }
+ }
});
}
@@ -1076,13 +1089,15 @@ ngFileUpload.service('Upload', ['$parse', '$timeout', '$compile', '$q', 'UploadE
var validateAfterResize = upload.attrGetter('ngfValidateAfterResize', attr, scope);
- var options = upload.attrGetter('ngModelOptions', attr, scope);
- upload.validate(allNewFiles, prevValidFiles.length, ngModel, attr, scope).then(function () {
+ var options = upload.attrGetter('ngfModelOptions', attr, scope);
+ upload.validate(allNewFiles, keep ? prevValidFiles.length : 0, ngModel, attr, scope)
+ .then(function (validationResult) {
if (noDelay) {
update(allNewFiles, [], files, dupFiles, isSingleModel);
} else {
if ((!options || !options.allowInvalid) && !validateAfterResize) {
- separateInvalids();
+ valids = validationResult.validFiles;
+ invalids = validationResult.invalidFiles;
} else {
valids = allNewFiles;
}
@@ -1119,7 +1134,7 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
/** @namespace attr.ngfSelect */
/** @namespace attr.ngfChange */
/** @namespace attr.ngModel */
- /** @namespace attr.ngModelOptions */
+ /** @namespace attr.ngfModelOptions */
/** @namespace attr.ngfMultiple */
/** @namespace attr.ngfCapture */
/** @namespace attr.ngfValidate */
@@ -1139,6 +1154,8 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
function changeFn(evt) {
if (upload.shouldUpdateOn('change', attr, scope)) {
var fileList = evt.__files_ || (evt.target && evt.target.files), files = [];
+ /* Handle duplicate call in IE11 */
+ if (!fileList) return;
for (var i = 0; i < fileList.length; i++) {
files.push(fileList[i]);
}
@@ -1150,31 +1167,39 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
upload.registerModelChangeValidator(ngModel, attr, scope);
var unwatches = [];
- unwatches.push(scope.$watch(attrGetter('ngfMultiple'), function () {
- fileElem.attr('multiple', attrGetter('ngfMultiple', scope));
- }));
- unwatches.push(scope.$watch(attrGetter('ngfCapture'), function () {
- fileElem.attr('capture', attrGetter('ngfCapture', scope));
- }));
- unwatches.push(scope.$watch(attrGetter('ngfAccept'), function () {
- fileElem.attr('accept', attrGetter('ngfAccept', scope));
- }));
- attr.$observe('accept', function () {
+ if (attrGetter('ngfMultiple')) {
+ unwatches.push(scope.$watch(attrGetter('ngfMultiple'), function () {
+ fileElem.attr('multiple', attrGetter('ngfMultiple', scope));
+ }));
+ }
+ if (attrGetter('ngfCapture')) {
+ unwatches.push(scope.$watch(attrGetter('ngfCapture'), function () {
+ fileElem.attr('capture', attrGetter('ngfCapture', scope));
+ }));
+ }
+ if (attrGetter('ngfAccept')) {
+ unwatches.push(scope.$watch(attrGetter('ngfAccept'), function () {
+ fileElem.attr('accept', attrGetter('ngfAccept', scope));
+ }));
+ }
+ unwatches.push(attr.$observe('accept', function () {
fileElem.attr('accept', attrGetter('accept'));
- });
- unwatches.push(function () {
- if (attr.$$observers) delete attr.$$observers.accept;
- });
- function bindAttrToFileInput(fileElem) {
- if (elem !== fileElem) {
- for (var i = 0; i < elem[0].attributes.length; i++) {
- var attribute = elem[0].attributes[i];
- if (attribute.name !== 'type' && attribute.name !== 'class' && attribute.name !== 'style') {
- if (attribute.value == null || attribute.value === '') {
- if (attribute.name === 'required') attribute.value = 'required';
- if (attribute.name === 'multiple') attribute.value = 'multiple';
- }
- fileElem.attr(attribute.name, attribute.name === 'id' ? 'ngf-' + attribute.value : attribute.value);
+ }));
+ function bindAttrToFileInput(fileElem, label) {
+ function updateId(val) {
+ fileElem.attr('id', 'ngf-' + val);
+ label.attr('id', 'ngf-label-' + val);
+ }
+
+ for (var i = 0; i < elem[0].attributes.length; i++) {
+ var attribute = elem[0].attributes[i];
+ if (attribute.name !== 'type' && attribute.name !== 'class' && attribute.name !== 'style') {
+ if (attribute.name === 'id') {
+ updateId(attribute.value);
+ unwatches.push(attr.$observe('id', updateId));
+ } else {
+ fileElem.attr(attribute.name, (!attribute.value && (attribute.name === 'required' ||
+ attribute.name === 'multiple')) ? attribute.name : attribute.value);
}
}
}
@@ -1187,12 +1212,12 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
var fileElem = angular.element('<input type="file">');
- bindAttrToFileInput(fileElem);
-
var label = angular.element('<label>upload</label>');
label.css('visibility', 'hidden').css('position', 'absolute').css('overflow', 'hidden')
.css('width', '0px').css('height', '0px').css('border', 'none')
.css('margin', '0px').css('padding', '0px').attr('tabindex', '-1');
+ bindAttrToFileInput(fileElem, label);
+
generatedElems.push({el: elem, ref: label});
document.body.appendChild(label.append(fileElem)[0]);
@@ -1200,13 +1225,12 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
return fileElem;
}
- var initialTouchStartY = 0;
-
function clickHandler(evt) {
if (elem.attr('disabled')) return false;
if (attrGetter('ngfSelectDisabled', scope)) return;
- var r = handleTouch(evt);
+ var r = detectSwipe(evt);
+ // prevent the click if it is a swipe
if (r != null) return r;
resetModel(evt);
@@ -1218,7 +1242,8 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
document.body.appendChild(fileElem.parent()[0]);
fileElem.bind('change', changeFn);
}
- } catch(e){/*ignore*/}
+ } catch (e) {/*ignore*/
+ }
if (isDelayedClickSupported(navigator.userAgent)) {
setTimeout(function () {
@@ -1231,19 +1256,30 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
return false;
}
- function handleTouch(evt) {
- var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches);
- if (evt.type === 'touchstart') {
- initialTouchStartY = touches ? touches[0].clientY : 0;
- return true; // don't block event default
- } else {
- evt.stopPropagation();
- evt.preventDefault();
- // prevent scroll from triggering event
- if (evt.type === 'touchend') {
- var currentLocation = touches ? touches[0].clientY : 0;
- if (Math.abs(currentLocation - initialTouchStartY) > 20) return false;
+ var initialTouchStartY = 0;
+ var initialTouchStartX = 0;
+
+ function detectSwipe(evt) {
+ var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches);
+ if (touches) {
+ if (evt.type === 'touchstart') {
+ initialTouchStartX = touches[0].clientX;
+ initialTouchStartY = touches[0].clientY;
+ return true; // don't block event default
+ } else {
+ // prevent scroll from triggering event
+ if (evt.type === 'touchend') {
+ var currentX = touches[0].clientX;
+ var currentY = touches[0].clientY;
+ if ((Math.abs(currentX - initialTouchStartX) > 20) ||
+ (Math.abs(currentY - initialTouchStartY) > 20)) {
+ evt.stopPropagation();
+ evt.preventDefault();
+ return false;
+ }
+ }
+ return true;
}
}
}
@@ -1474,14 +1510,19 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
var size = resizeParams;
if (directiveName === 'ngfThumbnail') {
if (!size) {
- size = {width: elem[0].clientWidth, height: elem[0].clientHeight};
+ size = {
+ width: elem[0].naturalWidth || elem[0].clientWidth,
+ height: elem[0].naturalHeight || elem[0].clientHeight
+ };
}
if (size.width === 0 && window.getComputedStyle) {
var style = getComputedStyle(elem[0]);
- size = {
- width: parseInt(style.width.slice(0, -2)),
- height: parseInt(style.height.slice(0, -2))
- };
+ if (style.width && style.width.indexOf('px') > -1 && style.height && style.height.indexOf('px') > -1) {
+ size = {
+ width: parseInt(style.width.slice(0, -2)),
+ height: parseInt(style.height.slice(0, -2))
+ };
+ }
}
}
@@ -1496,7 +1537,11 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
if (file && file.type && file.type.search(getTagType(elem[0])) === 0 &&
(!isBackground || file.type.indexOf('image') === 0)) {
if (size && Upload.isResizeSupported()) {
- Upload.resize(file, size.width, size.height, size.quality).then(
+ size.resizeIf = function (width, height) {
+ return Upload.attrGetter('ngfResizeIf', attr, scope,
+ {$width: width, $height: height, $file: file});
+ };
+ Upload.resize(file, size).then(
function (f) {
constructDataUrl(f);
}, function (e) {
@@ -1558,8 +1603,8 @@ ngFileUpload.directive('ngfSelect', ['$parse', '$timeout', '$compile', 'Upload',
}]);
ngFileUpload.config(['$compileProvider', function ($compileProvider) {
- if ($compileProvider.imgSrcSanitizationWhitelist) $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|local|file|data|blob):/);
- if ($compileProvider.aHrefSanitizationWhitelist) $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|local|file|data|blob):/);
+ if ($compileProvider.imgSrcSanitizationWhitelist) $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/);
+ if ($compileProvider.aHrefSanitizationWhitelist) $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/);
}]);
ngFileUpload.filter('ngfDataUrl', ['UploadDataUrl', '$sce', function (UploadDataUrl, $sce) {
@@ -1651,13 +1696,15 @@ ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', funct
if (ngModel) {
ngModel.$formatters.push(function (files) {
if (ngModel.$dirty) {
+ var filesArray = files;
if (files && !angular.isArray(files)) {
- files = [files];
+ filesArray = [files];
}
- upload.validate(files, 0, ngModel, attr, scope).then(function () {
- upload.applyModelValidation(ngModel, files);
+ upload.validate(filesArray, 0, ngModel, attr, scope).then(function () {
+ upload.applyModelValidation(ngModel, filesArray);
});
}
+ return files;
});
}
};
@@ -1707,11 +1754,15 @@ ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', funct
return upload.attrGetter(name, attr, scope, params);
};
+ var ignoredErrors = (upload.attrGetter('ngfIgnoreInvalid', attr, scope) || '').split(' ');
+ var runAllValidation = upload.attrGetter('ngfRunAllValidations', attr, scope);
+
if (files == null || files.length === 0) {
- return upload.emptyPromise(ngModel);
+ return upload.emptyPromise({'validFiles': files, 'invalidFiles': []});
}
files = files.length === undefined ? [files] : files.slice(0);
+ var invalidFiles = [];
function validateSync(name, validationName, fn) {
if (files) {
@@ -1722,11 +1773,20 @@ ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', funct
var val = upload.getValidationAttr(attr, scope, name, validationName, file);
if (val != null) {
if (!fn(file, val, i)) {
- file.$error = name;
- (file.$errorMessages = (file.$errorMessages || {}))[name] = true;
- file.$errorParam = val;
- files.splice(i, 1);
- valid = false;
+ if (ignoredErrors.indexOf(name) === -1) {
+ file.$error = name;
+ (file.$errorMessages = (file.$errorMessages || {}))[name] = true;
+ file.$errorParam = val;
+ if (invalidFiles.indexOf(file) === -1) {
+ invalidFiles.push(file);
+ }
+ if (!runAllValidation) {
+ files.splice(i, 1);
+ }
+ valid = false;
+ } else {
+ files.splice(i, 1);
+ }
}
}
}
@@ -1737,9 +1797,6 @@ ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', funct
}
}
- validateSync('maxFiles', null, function (file, val, i) {
- return prevLength + i < val;
- });
validateSync('pattern', null, upload.validatePattern);
validateSync('minSize', 'size.min', function (file, val) {
return file.size + 0.1 >= upload.translateScalars(val);
@@ -1762,44 +1819,58 @@ ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', funct
});
if (!files.length) {
- return upload.emptyPromise(ngModel, ngModel.$ngfValidations);
+ return upload.emptyPromise({'validFiles': [], 'invalidFiles': invalidFiles});
}
function validateAsync(name, validationName, type, asyncFn, fn) {
function resolveResult(defer, file, val) {
- if (val != null) {
- asyncFn(file, val).then(function (d) {
- if (!fn(d, val)) {
+ function resolveInternal(fn) {
+ if (fn()) {
+ if (ignoredErrors.indexOf(name) === -1) {
file.$error = name;
(file.$errorMessages = (file.$errorMessages || {}))[name] = true;
file.$errorParam = val;
- defer.reject();
+ if (invalidFiles.indexOf(file) === -1) {
+ invalidFiles.push(file);
+ }
+ if (!runAllValidation) {
+ var i = files.indexOf(file);
+ if (i > -1) files.splice(i, 1);
+ }
+ defer.resolve(false);
} else {
- defer.resolve();
+ var j = files.indexOf(file);
+ if (j > -1) files.splice(j, 1);
+ defer.resolve(true);
}
+ } else {
+ defer.resolve(true);
+ }
+ }
+
+ if (val != null) {
+ asyncFn(file, val).then(function (d) {
+ resolveInternal(function () {
+ return !fn(d, val);
+ });
}, function () {
- if (attrGetter('ngfValidateForce', {$file: file})) {
- file.$error = name;
- (file.$errorMessages = (file.$errorMessages || {}))[name] = true;
- file.$errorParam = val;
- defer.reject();
- } else {
- defer.resolve();
- }
+ resolveInternal(function () {
+ return attrGetter('ngfValidateForce', {$file: file});
+ });
});
} else {
- defer.resolve();
+ defer.resolve(true);
}
}
- var promises = [upload.emptyPromise()];
+ var promises = [upload.emptyPromise(true)];
if (files) {
files = files.length === undefined ? [files] : files;
angular.forEach(files, function (file) {
var defer = $q.defer();
promises.push(defer.promise);
if (type && (file.type == null || file.type.search(type) !== 0)) {
- defer.resolve();
+ defer.resolve(true);
return;
}
if (name === 'dimensions' && upload.attrGetter('ngfDimensions', attr) != null) {
@@ -1807,96 +1878,120 @@ ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', funct
resolveResult(defer, file,
attrGetter('ngfDimensions', {$file: file, $width: d.width, $height: d.height}));
}, function () {
- defer.reject();
+ defer.resolve(false);
});
} else if (name === 'duration' && upload.attrGetter('ngfDuration', attr) != null) {
upload.mediaDuration(file).then(function (d) {
resolveResult(defer, file,
attrGetter('ngfDuration', {$file: file, $duration: d}));
}, function () {
- defer.reject();
+ defer.resolve(false);
});
} else {
resolveResult(defer, file,
upload.getValidationAttr(attr, scope, name, validationName, file));
}
});
- return $q.all(promises).then(function () {
- ngModel.$ngfValidations.push({name: name, valid: true});
- }, function () {
- ngModel.$ngfValidations.push({name: name, valid: false});
- });
}
+ var deffer = $q.defer();
+ $q.all(promises).then(function (values) {
+ var isValid = true;
+ for (var i = 0; i < values.length; i++) {
+ if (!values[i]) {
+ isValid = false;
+ break;
+ }
+ }
+ ngModel.$ngfValidations.push({name: name, valid: isValid});
+ deffer.resolve(isValid);
+ });
+ return deffer.promise;
}
var deffer = $q.defer();
var promises = [];
- promises.push(upload.happyPromise(validateAsync('maxHeight', 'height.max', /image/,
+ promises.push(validateAsync('maxHeight', 'height.max', /image/,
this.imageDimensions, function (d, val) {
return d.height <= val;
- })));
- promises.push(upload.happyPromise(validateAsync('minHeight', 'height.min', /image/,
+ }));
+ promises.push(validateAsync('minHeight', 'height.min', /image/,
this.imageDimensions, function (d, val) {
return d.height >= val;
- })));
- promises.push(upload.happyPromise(validateAsync('maxWidth', 'width.max', /image/,
+ }));
+ promises.push(validateAsync('maxWidth', 'width.max', /image/,
this.imageDimensions, function (d, val) {
return d.width <= val;
- })));
- promises.push(upload.happyPromise(validateAsync('minWidth', 'width.min', /image/,
+ }));
+ promises.push(validateAsync('minWidth', 'width.min', /image/,
this.imageDimensions, function (d, val) {
return d.width >= val;
- })));
- promises.push(upload.happyPromise(validateAsync('dimensions', null, /image/,
+ }));
+ promises.push(validateAsync('dimensions', null, /image/,
function (file, val) {
return upload.emptyPromise(val);
}, function (r) {
return r;
- })));
- promises.push(upload.happyPromise(validateAsync('ratio', null, /image/,
+ }));
+ promises.push(validateAsync('ratio', null, /image/,
this.imageDimensions, function (d, val) {
var split = val.toString().split(','), valid = false;
for (var i = 0; i < split.length; i++) {
- if (Math.abs((d.width / d.height) - upload.ratioToFloat(split[i])) < 0.0001) {
+ if (Math.abs((d.width / d.height) - upload.ratioToFloat(split[i])) < 0.01) {
valid = true;
}
}
return valid;
- })));
- promises.push(upload.happyPromise(validateAsync('maxRatio', 'ratio.max', /image/,
+ }));
+ promises.push(validateAsync('maxRatio', 'ratio.max', /image/,
this.imageDimensions, function (d, val) {
return (d.width / d.height) - upload.ratioToFloat(val) < 0.0001;
- })));
- promises.push(upload.happyPromise(validateAsync('minRatio', 'ratio.min', /image/,
+ }));
+ promises.push(validateAsync('minRatio', 'ratio.min', /image/,
this.imageDimensions, function (d, val) {
return (d.width / d.height) - upload.ratioToFloat(val) > -0.0001;
- })));
- promises.push(upload.happyPromise(validateAsync('maxDuration', 'duration.max', /audio|video/,
+ }));
+ promises.push(validateAsync('maxDuration', 'duration.max', /audio|video/,
this.mediaDuration, function (d, val) {
return d <= upload.translateScalars(val);
- })));
- promises.push(upload.happyPromise(validateAsync('minDuration', 'duration.min', /audio|video/,
+ }));
+ promises.push(validateAsync('minDuration', 'duration.min', /audio|video/,
this.mediaDuration, function (d, val) {
return d >= upload.translateScalars(val);
- })));
- promises.push(upload.happyPromise(validateAsync('duration', null, /audio|video/,
+ }));
+ promises.push(validateAsync('duration', null, /audio|video/,
function (file, val) {
return upload.emptyPromise(val);
}, function (r) {
return r;
- })));
+ }));
- promises.push(upload.happyPromise(validateAsync('validateAsyncFn', null, null,
+ promises.push(validateAsync('validateAsyncFn', null, null,
function (file, val) {
return val;
}, function (r) {
return r === true || r === null || r === '';
- })));
+ }));
- return $q.all(promises).then(function () {
- deffer.resolve(ngModel, ngModel.$ngfValidations);
+ $q.all(promises).then(function () {
+
+ if (runAllValidation) {
+ for (var i = 0; i < files.length; i++) {
+ var file = files[i];
+ if (file.$error) {
+ files.splice(i--, 1);
+ }
+ }
+ }
+
+ runAllValidation = false;
+ validateSync('maxFiles', null, function (file, val, i) {
+ return prevLength + i < val;
+ });
+
+ deffer.resolve({'validFiles': files, 'invalidFiles': invalidFiles});
});
+ return deffer.promise;
};
upload.imageDimensions = function (file) {
@@ -1921,8 +2016,8 @@ ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', funct
.css('max-width', 'none !important').css('max-height', 'none !important');
function success() {
- var width = img[0].clientWidth;
- var height = img[0].clientHeight;
+ var width = img[0].naturalWidth || img[0].clientWidth;
+ var height = img[0].naturalHeight || img[0].clientHeight;
img.remove();
file.$ngfWidth = width;
file.$ngfHeight = height;
@@ -1936,23 +2031,23 @@ ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', funct
img.on('load', success);
img.on('error', error);
- var count = 0;
- function checkLoadError() {
+ var secondsCounter = 0;
+ function checkLoadErrorInCaseOfNoCallback() {
$timeout(function () {
if (img[0].parentNode) {
if (img[0].clientWidth) {
success();
- } else if (count > 10) {
+ } else if (secondsCounter++ > 10) {
error();
} else {
- checkLoadError();
+ checkLoadErrorInCaseOfNoCallback();
}
}
}, 1000);
}
- checkLoadError();
+ checkLoadErrorInCaseOfNoCallback();
angular.element(document.getElementsByTagName('body')[0]).append(img);
}, function () {
@@ -2063,31 +2158,35 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
var deferred = $q.defer();
var canvasElement = document.createElement('canvas');
var imageElement = document.createElement('img');
+ imageElement.setAttribute('style', 'visibility:hidden;position:fixed;z-index:-100000');
+ document.body.appendChild(imageElement);
imageElement.onload = function () {
- if (resizeIf != null && resizeIf(imageElement.width, imageElement.height) === false) {
+ var imgWidth = imageElement.width, imgHeight = imageElement.height;
+ imageElement.parentNode.removeChild(imageElement);
+ if (resizeIf != null && resizeIf(imgWidth, imgHeight) === false) {
deferred.reject('resizeIf');
return;
}
try {
if (ratio) {
var ratioFloat = upload.ratioToFloat(ratio);
- var imgRatio = imageElement.width / imageElement.height;
+ var imgRatio = imgWidth / imgHeight;
if (imgRatio < ratioFloat) {
- width = imageElement.width;
+ width = imgWidth;
height = width / ratioFloat;
} else {
- height = imageElement.height;
+ height = imgHeight;
width = height * ratioFloat;
}
}
if (!width) {
- width = imageElement.width;
+ width = imgWidth;
}
if (!height) {
- height = imageElement.height;
+ height = imgHeight;
}
- var dimensions = calculateAspectRatioFit(imageElement.width, imageElement.height, width, height, centerCrop);
+ var dimensions = calculateAspectRatioFit(imgWidth, imgHeight, width, height, centerCrop);
canvasElement.width = Math.min(dimensions.width, width);
canvasElement.height = Math.min(dimensions.height, height);
var context = canvasElement.getContext('2d');
@@ -2100,6 +2199,7 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
}
};
imageElement.onerror = function () {
+ imageElement.parentNode.removeChild(imageElement);
deferred.reject();
};
imageElement.src = imagen;
@@ -2136,14 +2236,15 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
});
}
- upload.resize = function (file, width, height, quality, type, ratio, centerCrop, resizeIf, restoreExif) {
+ upload.resize = function (file, options) {
if (file.type.indexOf('image') !== 0) return upload.emptyPromise(file);
var deferred = $q.defer();
upload.dataUrl(file, true).then(function (url) {
- resize(url, width, height, quality, type || file.type, ratio, centerCrop, resizeIf)
+ resize(url, options.width, options.height, options.quality, options.type || file.type,
+ options.ratio, options.centerCrop, options.resizeIf)
.then(function (dataUrl) {
- if (file.type === 'image/jpeg' && restoreExif) {
+ if (file.type === 'image/jpeg' && options.restoreExif !== false) {
try {
dataUrl = upload.restoreExif(url, dataUrl);
} catch (e) {
@@ -2172,13 +2273,13 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
}]);
(function () {
- ngFileUpload.directive('ngfDrop', ['$parse', '$timeout', '$location', 'Upload', '$http', '$q',
- function ($parse, $timeout, $location, Upload, $http, $q) {
+ ngFileUpload.directive('ngfDrop', ['$parse', '$timeout', '$window', 'Upload', '$http', '$q',
+ function ($parse, $timeout, $window, Upload, $http, $q) {
return {
restrict: 'AEC',
require: '?ngModel',
link: function (scope, elem, attr, ngModel) {
- linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location, Upload, $http, $q);
+ linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $window, Upload, $http, $q);
}
};
}]);
@@ -2203,7 +2304,7 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
};
}]);
- function linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location, upload, $http, $q) {
+ function linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $window, upload, $http, $q) {
var available = dropAvailable();
var attrGetter = function (name, scope, params) {
@@ -2279,23 +2380,7 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
if (stopPropagation(scope)) evt.stopPropagation();
if (actualDragOverClass) elem.removeClass(actualDragOverClass);
actualDragOverClass = null;
- var items = evt.dataTransfer.items;
- var html;
- try {
- html = evt.dataTransfer && evt.dataTransfer.getData && evt.dataTransfer.getData('text/html');
- } catch (e) {/* Fix IE11 that throw error calling getData */
- }
-
- extractFiles(items, evt.dataTransfer.files, attrGetter('ngfAllowDir', scope) !== false,
- attrGetter('multiple') || attrGetter('ngfMultiple', scope)).then(function (files) {
- if (files.length) {
- updateModel(files, evt);
- } else {
- extractFilesFromHtml('dropUrl', html).then(function (files) {
- updateModel(files, evt);
- });
- }
- });
+ extractFilesAndUpdateModel(evt.dataTransfer, evt, 'dropUrl');
}, false);
elem[0].addEventListener('paste', function (evt) {
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1 &&
@@ -2303,22 +2388,7 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
evt.preventDefault();
}
if (isDisabled() || !upload.shouldUpdateOn('paste', attr, scope)) return;
- var files = [];
- var clipboard = evt.clipboardData || evt.originalEvent.clipboardData;
- if (clipboard && clipboard.items) {
- for (var k = 0; k < clipboard.items.length; k++) {
- if (clipboard.items[k].type.indexOf('image') !== -1) {
- files.push(clipboard.items[k].getAsFile());
- }
- }
- }
- if (files.length) {
- updateModel(files, evt);
- } else {
- extractFilesFromHtml('pasteUrl', clipboard).then(function (files) {
- updateModel(files, evt);
- });
- }
+ extractFilesAndUpdateModel(evt.clipboardData || evt.originalEvent.clipboardData, evt, 'pasteUrl');
}, false);
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1 &&
@@ -2331,12 +2401,33 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
});
}
+ function extractFilesAndUpdateModel(source, evt, updateOnType) {
+ if (!source) return;
+ // html needs to be calculated on the same process otherwise the data will be wiped
+ // after promise resolve or setTimeout.
+ var html;
+ try {
+ html = source && source.getData && source.getData('text/html');
+ } catch (e) {/* Fix IE11 that throw error calling getData */
+ }
+ extractFiles(source.items, source.files, attrGetter('ngfAllowDir', scope) !== false,
+ attrGetter('multiple') || attrGetter('ngfMultiple', scope)).then(function (files) {
+ if (files.length) {
+ updateModel(files, evt);
+ } else {
+ extractFilesFromHtml(updateOnType, html).then(function (files) {
+ updateModel(files, evt);
+ });
+ }
+ });
+ }
+
function updateModel(files, evt) {
upload.updateModel(ngModel, attr, scope, attrGetter('ngfChange') || attrGetter('ngfDrop'), files, evt);
}
function extractFilesFromHtml(updateOn, html) {
- if (!upload.shouldUpdateOn(updateOn, attr, scope) || !html) return upload.rejectPromise([]);
+ if (!upload.shouldUpdateOn(updateOn, attr, scope) || typeof html !== 'string') return upload.rejectPromise([]);
var urls = [];
html.replace(/<(img src|img [^>]* src) *=\"([^\"]*)\"/gi, function (m, n, src) {
urls.push(src);
@@ -2387,8 +2478,14 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
}
function extractFiles(items, fileList, allowDir, multiple) {
- var maxFiles = upload.getValidationAttr(attr, scope, 'maxFiles') || Number.MAX_VALUE;
- var maxTotalSize = upload.getValidationAttr(attr, scope, 'maxTotalSize') || Number.MAX_VALUE;
+ var maxFiles = upload.getValidationAttr(attr, scope, 'maxFiles');
+ if (maxFiles == null) {
+ maxFiles = Number.MAX_VALUE;
+ }
+ var maxTotalSize = upload.getValidationAttr(attr, scope, 'maxTotalSize');
+ if (maxTotalSize == null) {
+ maxTotalSize = Number.MAX_VALUE;
+ }
var includeDir = attrGetter('ngfIncludeDir', scope);
var files = [], totalSize = 0;
@@ -2399,7 +2496,7 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
var promises = [upload.emptyPromise()];
if (includeDir) {
var file = {type: 'directory'};
- file.name = file.path = (path || '') + entry.name + entry.name;
+ file.name = file.path = (path || '') + entry.name;
files.push(file);
}
var dirReader = entry.createReader();
@@ -2453,7 +2550,7 @@ ngFileUpload.service('UploadResize', ['UploadValidate', '$q', function (UploadVa
var promises = [upload.emptyPromise()];
- if (items && items.length > 0 && $location.protocol() !== 'file') {
+ if (items && items.length > 0 && $window.location.protocol !== 'file:') {
for (var i = 0; i < items.length; i++) {
if (items[i].webkitGetAsEntry && items[i].webkitGetAsEntry() && items[i].webkitGetAsEntry().isDirectory) {
var entry = items[i].webkitGetAsEntry();