UNPKG

ng-file-upload-haikulearning

Version:

An AngularJS directive for file upload using HTML5 with FileAPI polyfill for unsupported browsers

248 lines (232 loc) 9.16 kB
(function () { ngFileUpload.service('UploadDataUrl', ['UploadBase', '$timeout', '$q', function (UploadBase, $timeout, $q) { var upload = UploadBase; upload.base64DataUrl = function (file) { if (angular.isArray(file)) { var d = $q.defer(), count = 0; angular.forEach(file, function (f) { upload.dataUrl(f, true)['finally'](function () { count++; if (count === file.length) { var urls = []; angular.forEach(file, function (ff) { urls.push(ff.$ngfDataUrl); }); d.resolve(urls, file); } }); }); return d.promise; } else { return upload.dataUrl(file, true); } }; upload.dataUrl = function (file, disallowObjectUrl) { if (!file) return upload.emptyPromise(file, file); if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { return upload.emptyPromise(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl, file); } var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; if (p) return p; var deferred = $q.defer(); $timeout(function () { if (window.FileReader && file && (!window.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && (!window.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { //prefer URL.createObjectURL for handling refrences to files of all sizes //since it doesn´t build a large string in memory var URL = window.URL || window.webkitURL; if (URL && URL.createObjectURL && !disallowObjectUrl) { var url; try { url = URL.createObjectURL(file); } catch (e) { $timeout(function () { file.$ngfBlobUrl = ''; deferred.reject(); }); return; } $timeout(function () { file.$ngfBlobUrl = url; if (url) { deferred.resolve(url, file); upload.blobUrls = upload.blobUrls || []; upload.blobUrlsTotalSize = upload.blobUrlsTotalSize || 0; upload.blobUrls.push({url: url, size: file.size}); upload.blobUrlsTotalSize += file.size || 0; var maxMemory = upload.defaults.blobUrlsMaxMemory || 268435456; var maxLength = upload.defaults.blobUrlsMaxQueueSize || 200; while ((upload.blobUrlsTotalSize > maxMemory || upload.blobUrls.length > maxLength) && upload.blobUrls.length > 1) { var obj = upload.blobUrls.splice(0, 1)[0]; URL.revokeObjectURL(obj.url); upload.blobUrlsTotalSize -= obj.size; } } }); } else { var fileReader = new FileReader(); fileReader.onload = function (e) { $timeout(function () { file.$ngfDataUrl = e.target.result; deferred.resolve(e.target.result, file); $timeout(function () { delete file.$ngfDataUrl; }, 1000); }); }; fileReader.onerror = function () { $timeout(function () { file.$ngfDataUrl = ''; deferred.reject(); }); }; fileReader.readAsDataURL(file); } } else { $timeout(function () { file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; deferred.reject(); }); } }); if (disallowObjectUrl) { p = file.$$ngfDataUrlPromise = deferred.promise; } else { p = file.$$ngfBlobUrlPromise = deferred.promise; } p['finally'](function () { delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; }); return p; }; return upload; }]); function getTagType(el) { if (el.tagName.toLowerCase() === 'img') return 'image'; if (el.tagName.toLowerCase() === 'audio') return 'audio'; if (el.tagName.toLowerCase() === 'video') return 'video'; return /./; } function linkFileDirective(Upload, $timeout, scope, elem, attr, directiveName, resizeParams, isBackground) { function constructDataUrl(file) { var disallowObjectUrl = Upload.attrGetter('ngfNoObjectUrl', attr, scope); Upload.dataUrl(file, disallowObjectUrl)['finally'](function () { $timeout(function () { var src = (disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl; if (isBackground) { elem.css('background-image', 'url(\'' + (src || '') + '\')'); } else { elem.attr('src', src); } if (src) { elem.removeClass('ng-hide'); } else { elem.addClass('ng-hide'); } }); }); } $timeout(function () { var unwatch = scope.$watch(attr[directiveName], function (file) { var size = resizeParams; if (directiveName === 'ngfThumbnail') { if (!size) { size = {width: elem[0].clientWidth, height: 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 (angular.isString(file)) { elem.removeClass('ng-hide'); if (isBackground) { return elem.css('background-image', 'url(\'' + file + '\')'); } else { return elem.attr('src', file); } } 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( function (f) { constructDataUrl(f); }, function (e) { throw e; } ); } else { constructDataUrl(file); } } else { elem.addClass('ng-hide'); } }); scope.$on('$destroy', function () { unwatch(); }); }); } /** @namespace attr.ngfSrc */ /** @namespace attr.ngfNoObjectUrl */ ngFileUpload.directive('ngfSrc', ['Upload', '$timeout', function (Upload, $timeout) { return { restrict: 'AE', link: function (scope, elem, attr) { linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfSrc', Upload.attrGetter('ngfResize', attr, scope), false); } }; }]); /** @namespace attr.ngfBackground */ /** @namespace attr.ngfNoObjectUrl */ ngFileUpload.directive('ngfBackground', ['Upload', '$timeout', function (Upload, $timeout) { return { restrict: 'AE', link: function (scope, elem, attr) { linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfBackground', Upload.attrGetter('ngfResize', attr, scope), true); } }; }]); /** @namespace attr.ngfThumbnail */ /** @namespace attr.ngfAsBackground */ /** @namespace attr.ngfSize */ /** @namespace attr.ngfNoObjectUrl */ ngFileUpload.directive('ngfThumbnail', ['Upload', '$timeout', function (Upload, $timeout) { return { restrict: 'AE', link: function (scope, elem, attr) { var size = Upload.attrGetter('ngfSize', attr, scope); linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfThumbnail', size, Upload.attrGetter('ngfAsBackground', attr, scope)); } }; }]); 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):/); }]); ngFileUpload.filter('ngfDataUrl', ['UploadDataUrl', '$sce', function (UploadDataUrl, $sce) { return function (file, disallowObjectUrl, trustedUrl) { if (angular.isString(file)) { return $sce.trustAsResourceUrl(file); } var src = file && ((disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl); if (file && !src) { if (!file.$ngfDataUrlFilterInProgress && angular.isObject(file)) { file.$ngfDataUrlFilterInProgress = true; UploadDataUrl.dataUrl(file, disallowObjectUrl); } return ''; } if (file) delete file.$ngfDataUrlFilterInProgress; return (file && src ? (trustedUrl ? $sce.trustAsResourceUrl(src) : src) : file) || ''; }; }]); })();