@@ 1373-1624 (lines=252) @@ | ||
1370 | }; |
|
1371 | }]); |
|
1372 | ||
1373 | (function () { |
|
1374 | ||
1375 | ngFileUpload.service('UploadDataUrl', ['UploadBase', '$timeout', '$q', function (UploadBase, $timeout, $q) { |
|
1376 | var upload = UploadBase; |
|
1377 | upload.base64DataUrl = function (file) { |
|
1378 | if (angular.isArray(file)) { |
|
1379 | var d = $q.defer(), count = 0; |
|
1380 | angular.forEach(file, function (f) { |
|
1381 | upload.dataUrl(f, true)['finally'](function () { |
|
1382 | count++; |
|
1383 | if (count === file.length) { |
|
1384 | var urls = []; |
|
1385 | angular.forEach(file, function (ff) { |
|
1386 | urls.push(ff.$ngfDataUrl); |
|
1387 | }); |
|
1388 | d.resolve(urls, file); |
|
1389 | } |
|
1390 | }); |
|
1391 | }); |
|
1392 | return d.promise; |
|
1393 | } else { |
|
1394 | return upload.dataUrl(file, true); |
|
1395 | } |
|
1396 | }; |
|
1397 | upload.dataUrl = function (file, disallowObjectUrl) { |
|
1398 | if (!file) return upload.emptyPromise(file, file); |
|
1399 | if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { |
|
1400 | return upload.emptyPromise(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl, file); |
|
1401 | } |
|
1402 | var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; |
|
1403 | if (p) return p; |
|
1404 | ||
1405 | var deferred = $q.defer(); |
|
1406 | $timeout(function () { |
|
1407 | if (window.FileReader && file && |
|
1408 | (!window.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && |
|
1409 | (!window.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { |
|
1410 | //prefer URL.createObjectURL for handling refrences to files of all sizes |
|
1411 | //since it doesn´t build a large string in memory |
|
1412 | var URL = window.URL || window.webkitURL; |
|
1413 | if (URL && URL.createObjectURL && !disallowObjectUrl) { |
|
1414 | var url; |
|
1415 | try { |
|
1416 | url = URL.createObjectURL(file); |
|
1417 | } catch (e) { |
|
1418 | $timeout(function () { |
|
1419 | file.$ngfBlobUrl = ''; |
|
1420 | deferred.reject(); |
|
1421 | }); |
|
1422 | return; |
|
1423 | } |
|
1424 | $timeout(function () { |
|
1425 | file.$ngfBlobUrl = url; |
|
1426 | if (url) { |
|
1427 | deferred.resolve(url, file); |
|
1428 | upload.blobUrls = upload.blobUrls || []; |
|
1429 | upload.blobUrlsTotalSize = upload.blobUrlsTotalSize || 0; |
|
1430 | upload.blobUrls.push({url: url, size: file.size}); |
|
1431 | upload.blobUrlsTotalSize += file.size || 0; |
|
1432 | var maxMemory = upload.defaults.blobUrlsMaxMemory || 268435456; |
|
1433 | var maxLength = upload.defaults.blobUrlsMaxQueueSize || 200; |
|
1434 | while ((upload.blobUrlsTotalSize > maxMemory || upload.blobUrls.length > maxLength) && upload.blobUrls.length > 1) { |
|
1435 | var obj = upload.blobUrls.splice(0, 1)[0]; |
|
1436 | URL.revokeObjectURL(obj.url); |
|
1437 | upload.blobUrlsTotalSize -= obj.size; |
|
1438 | } |
|
1439 | } |
|
1440 | }); |
|
1441 | } else { |
|
1442 | var fileReader = new FileReader(); |
|
1443 | fileReader.onload = function (e) { |
|
1444 | $timeout(function () { |
|
1445 | file.$ngfDataUrl = e.target.result; |
|
1446 | deferred.resolve(e.target.result, file); |
|
1447 | $timeout(function () { |
|
1448 | delete file.$ngfDataUrl; |
|
1449 | }, 1000); |
|
1450 | }); |
|
1451 | }; |
|
1452 | fileReader.onerror = function () { |
|
1453 | $timeout(function () { |
|
1454 | file.$ngfDataUrl = ''; |
|
1455 | deferred.reject(); |
|
1456 | }); |
|
1457 | }; |
|
1458 | fileReader.readAsDataURL(file); |
|
1459 | } |
|
1460 | } else { |
|
1461 | $timeout(function () { |
|
1462 | file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; |
|
1463 | deferred.reject(); |
|
1464 | }); |
|
1465 | } |
|
1466 | }); |
|
1467 | ||
1468 | if (disallowObjectUrl) { |
|
1469 | p = file.$$ngfDataUrlPromise = deferred.promise; |
|
1470 | } else { |
|
1471 | p = file.$$ngfBlobUrlPromise = deferred.promise; |
|
1472 | } |
|
1473 | p['finally'](function () { |
|
1474 | delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; |
|
1475 | }); |
|
1476 | return p; |
|
1477 | }; |
|
1478 | return upload; |
|
1479 | }]); |
|
1480 | ||
1481 | function getTagType(el) { |
|
1482 | if (el.tagName.toLowerCase() === 'img') return 'image'; |
|
1483 | if (el.tagName.toLowerCase() === 'audio') return 'audio'; |
|
1484 | if (el.tagName.toLowerCase() === 'video') return 'video'; |
|
1485 | return /./; |
|
1486 | } |
|
1487 | ||
1488 | function linkFileDirective(Upload, $timeout, scope, elem, attr, directiveName, resizeParams, isBackground) { |
|
1489 | function constructDataUrl(file) { |
|
1490 | var disallowObjectUrl = Upload.attrGetter('ngfNoObjectUrl', attr, scope); |
|
1491 | Upload.dataUrl(file, disallowObjectUrl)['finally'](function () { |
|
1492 | $timeout(function () { |
|
1493 | var src = (disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl; |
|
1494 | if (isBackground) { |
|
1495 | elem.css('background-image', 'url(\'' + (src || '') + '\')'); |
|
1496 | } else { |
|
1497 | elem.attr('src', src); |
|
1498 | } |
|
1499 | if (src) { |
|
1500 | elem.removeClass('ng-hide'); |
|
1501 | } else { |
|
1502 | elem.addClass('ng-hide'); |
|
1503 | } |
|
1504 | }); |
|
1505 | }); |
|
1506 | } |
|
1507 | ||
1508 | $timeout(function () { |
|
1509 | var unwatch = scope.$watch(attr[directiveName], function (file) { |
|
1510 | var size = resizeParams; |
|
1511 | if (directiveName === 'ngfThumbnail') { |
|
1512 | if (!size) { |
|
1513 | size = {width: elem[0].naturalWidth || elem[0].clientWidth, |
|
1514 | height: elem[0].naturalHeight || elem[0].clientHeight}; |
|
1515 | } |
|
1516 | if (size.width === 0 && window.getComputedStyle) { |
|
1517 | var style = getComputedStyle(elem[0]); |
|
1518 | size = { |
|
1519 | width: parseInt(style.width.slice(0, -2)), |
|
1520 | height: parseInt(style.height.slice(0, -2)) |
|
1521 | }; |
|
1522 | } |
|
1523 | } |
|
1524 | ||
1525 | if (angular.isString(file)) { |
|
1526 | elem.removeClass('ng-hide'); |
|
1527 | if (isBackground) { |
|
1528 | return elem.css('background-image', 'url(\'' + file + '\')'); |
|
1529 | } else { |
|
1530 | return elem.attr('src', file); |
|
1531 | } |
|
1532 | } |
|
1533 | if (file && file.type && file.type.search(getTagType(elem[0])) === 0 && |
|
1534 | (!isBackground || file.type.indexOf('image') === 0)) { |
|
1535 | if (size && Upload.isResizeSupported()) { |
|
1536 | size.resizeIf = function (width, height) { |
|
1537 | return Upload.attrGetter('ngfResizeIf', attr, scope, |
|
1538 | {$width: width, $height: height, $file: file}); |
|
1539 | }; |
|
1540 | Upload.resize(file, size).then( |
|
1541 | function (f) { |
|
1542 | constructDataUrl(f); |
|
1543 | }, function (e) { |
|
1544 | throw e; |
|
1545 | } |
|
1546 | ); |
|
1547 | } else { |
|
1548 | constructDataUrl(file); |
|
1549 | } |
|
1550 | } else { |
|
1551 | elem.addClass('ng-hide'); |
|
1552 | } |
|
1553 | }); |
|
1554 | ||
1555 | scope.$on('$destroy', function () { |
|
1556 | unwatch(); |
|
1557 | }); |
|
1558 | }); |
|
1559 | } |
|
1560 | ||
1561 | ||
1562 | /** @namespace attr.ngfSrc */ |
|
1563 | /** @namespace attr.ngfNoObjectUrl */ |
|
1564 | ngFileUpload.directive('ngfSrc', ['Upload', '$timeout', function (Upload, $timeout) { |
|
1565 | return { |
|
1566 | restrict: 'AE', |
|
1567 | link: function (scope, elem, attr) { |
|
1568 | linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfSrc', |
|
1569 | Upload.attrGetter('ngfResize', attr, scope), false); |
|
1570 | } |
|
1571 | }; |
|
1572 | }]); |
|
1573 | ||
1574 | /** @namespace attr.ngfBackground */ |
|
1575 | /** @namespace attr.ngfNoObjectUrl */ |
|
1576 | ngFileUpload.directive('ngfBackground', ['Upload', '$timeout', function (Upload, $timeout) { |
|
1577 | return { |
|
1578 | restrict: 'AE', |
|
1579 | link: function (scope, elem, attr) { |
|
1580 | linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfBackground', |
|
1581 | Upload.attrGetter('ngfResize', attr, scope), true); |
|
1582 | } |
|
1583 | }; |
|
1584 | }]); |
|
1585 | ||
1586 | /** @namespace attr.ngfThumbnail */ |
|
1587 | /** @namespace attr.ngfAsBackground */ |
|
1588 | /** @namespace attr.ngfSize */ |
|
1589 | /** @namespace attr.ngfNoObjectUrl */ |
|
1590 | ngFileUpload.directive('ngfThumbnail', ['Upload', '$timeout', function (Upload, $timeout) { |
|
1591 | return { |
|
1592 | restrict: 'AE', |
|
1593 | link: function (scope, elem, attr) { |
|
1594 | var size = Upload.attrGetter('ngfSize', attr, scope); |
|
1595 | linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfThumbnail', size, |
|
1596 | Upload.attrGetter('ngfAsBackground', attr, scope)); |
|
1597 | } |
|
1598 | }; |
|
1599 | }]); |
|
1600 | ||
1601 | ngFileUpload.config(['$compileProvider', function ($compileProvider) { |
|
1602 | if ($compileProvider.imgSrcSanitizationWhitelist) $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/); |
|
1603 | if ($compileProvider.aHrefSanitizationWhitelist) $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/); |
|
1604 | }]); |
|
1605 | ||
1606 | ngFileUpload.filter('ngfDataUrl', ['UploadDataUrl', '$sce', function (UploadDataUrl, $sce) { |
|
1607 | return function (file, disallowObjectUrl, trustedUrl) { |
|
1608 | if (angular.isString(file)) { |
|
1609 | return $sce.trustAsResourceUrl(file); |
|
1610 | } |
|
1611 | var src = file && ((disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl); |
|
1612 | if (file && !src) { |
|
1613 | if (!file.$ngfDataUrlFilterInProgress && angular.isObject(file)) { |
|
1614 | file.$ngfDataUrlFilterInProgress = true; |
|
1615 | UploadDataUrl.dataUrl(file, disallowObjectUrl); |
|
1616 | } |
|
1617 | return ''; |
|
1618 | } |
|
1619 | if (file) delete file.$ngfDataUrlFilterInProgress; |
|
1620 | return (file && src ? (trustedUrl ? $sce.trustAsResourceUrl(src) : src) : file) || ''; |
|
1621 | }; |
|
1622 | }]); |
|
1623 | ||
1624 | })(); |
|
1625 | ||
1626 | ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', function (UploadDataUrl, $q, $timeout) { |
|
1627 | var upload = UploadDataUrl; |
@@ 951-1202 (lines=252) @@ | ||
948 | }; |
|
949 | }]); |
|
950 | ||
951 | (function () { |
|
952 | ||
953 | ngFileUpload.service('UploadDataUrl', ['UploadBase', '$timeout', '$q', function (UploadBase, $timeout, $q) { |
|
954 | var upload = UploadBase; |
|
955 | upload.base64DataUrl = function (file) { |
|
956 | if (angular.isArray(file)) { |
|
957 | var d = $q.defer(), count = 0; |
|
958 | angular.forEach(file, function (f) { |
|
959 | upload.dataUrl(f, true)['finally'](function () { |
|
960 | count++; |
|
961 | if (count === file.length) { |
|
962 | var urls = []; |
|
963 | angular.forEach(file, function (ff) { |
|
964 | urls.push(ff.$ngfDataUrl); |
|
965 | }); |
|
966 | d.resolve(urls, file); |
|
967 | } |
|
968 | }); |
|
969 | }); |
|
970 | return d.promise; |
|
971 | } else { |
|
972 | return upload.dataUrl(file, true); |
|
973 | } |
|
974 | }; |
|
975 | upload.dataUrl = function (file, disallowObjectUrl) { |
|
976 | if (!file) return upload.emptyPromise(file, file); |
|
977 | if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { |
|
978 | return upload.emptyPromise(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl, file); |
|
979 | } |
|
980 | var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; |
|
981 | if (p) return p; |
|
982 | ||
983 | var deferred = $q.defer(); |
|
984 | $timeout(function () { |
|
985 | if (window.FileReader && file && |
|
986 | (!window.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && |
|
987 | (!window.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { |
|
988 | //prefer URL.createObjectURL for handling refrences to files of all sizes |
|
989 | //since it doesn´t build a large string in memory |
|
990 | var URL = window.URL || window.webkitURL; |
|
991 | if (URL && URL.createObjectURL && !disallowObjectUrl) { |
|
992 | var url; |
|
993 | try { |
|
994 | url = URL.createObjectURL(file); |
|
995 | } catch (e) { |
|
996 | $timeout(function () { |
|
997 | file.$ngfBlobUrl = ''; |
|
998 | deferred.reject(); |
|
999 | }); |
|
1000 | return; |
|
1001 | } |
|
1002 | $timeout(function () { |
|
1003 | file.$ngfBlobUrl = url; |
|
1004 | if (url) { |
|
1005 | deferred.resolve(url, file); |
|
1006 | upload.blobUrls = upload.blobUrls || []; |
|
1007 | upload.blobUrlsTotalSize = upload.blobUrlsTotalSize || 0; |
|
1008 | upload.blobUrls.push({url: url, size: file.size}); |
|
1009 | upload.blobUrlsTotalSize += file.size || 0; |
|
1010 | var maxMemory = upload.defaults.blobUrlsMaxMemory || 268435456; |
|
1011 | var maxLength = upload.defaults.blobUrlsMaxQueueSize || 200; |
|
1012 | while ((upload.blobUrlsTotalSize > maxMemory || upload.blobUrls.length > maxLength) && upload.blobUrls.length > 1) { |
|
1013 | var obj = upload.blobUrls.splice(0, 1)[0]; |
|
1014 | URL.revokeObjectURL(obj.url); |
|
1015 | upload.blobUrlsTotalSize -= obj.size; |
|
1016 | } |
|
1017 | } |
|
1018 | }); |
|
1019 | } else { |
|
1020 | var fileReader = new FileReader(); |
|
1021 | fileReader.onload = function (e) { |
|
1022 | $timeout(function () { |
|
1023 | file.$ngfDataUrl = e.target.result; |
|
1024 | deferred.resolve(e.target.result, file); |
|
1025 | $timeout(function () { |
|
1026 | delete file.$ngfDataUrl; |
|
1027 | }, 1000); |
|
1028 | }); |
|
1029 | }; |
|
1030 | fileReader.onerror = function () { |
|
1031 | $timeout(function () { |
|
1032 | file.$ngfDataUrl = ''; |
|
1033 | deferred.reject(); |
|
1034 | }); |
|
1035 | }; |
|
1036 | fileReader.readAsDataURL(file); |
|
1037 | } |
|
1038 | } else { |
|
1039 | $timeout(function () { |
|
1040 | file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; |
|
1041 | deferred.reject(); |
|
1042 | }); |
|
1043 | } |
|
1044 | }); |
|
1045 | ||
1046 | if (disallowObjectUrl) { |
|
1047 | p = file.$$ngfDataUrlPromise = deferred.promise; |
|
1048 | } else { |
|
1049 | p = file.$$ngfBlobUrlPromise = deferred.promise; |
|
1050 | } |
|
1051 | p['finally'](function () { |
|
1052 | delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; |
|
1053 | }); |
|
1054 | return p; |
|
1055 | }; |
|
1056 | return upload; |
|
1057 | }]); |
|
1058 | ||
1059 | function getTagType(el) { |
|
1060 | if (el.tagName.toLowerCase() === 'img') return 'image'; |
|
1061 | if (el.tagName.toLowerCase() === 'audio') return 'audio'; |
|
1062 | if (el.tagName.toLowerCase() === 'video') return 'video'; |
|
1063 | return /./; |
|
1064 | } |
|
1065 | ||
1066 | function linkFileDirective(Upload, $timeout, scope, elem, attr, directiveName, resizeParams, isBackground) { |
|
1067 | function constructDataUrl(file) { |
|
1068 | var disallowObjectUrl = Upload.attrGetter('ngfNoObjectUrl', attr, scope); |
|
1069 | Upload.dataUrl(file, disallowObjectUrl)['finally'](function () { |
|
1070 | $timeout(function () { |
|
1071 | var src = (disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl; |
|
1072 | if (isBackground) { |
|
1073 | elem.css('background-image', 'url(\'' + (src || '') + '\')'); |
|
1074 | } else { |
|
1075 | elem.attr('src', src); |
|
1076 | } |
|
1077 | if (src) { |
|
1078 | elem.removeClass('ng-hide'); |
|
1079 | } else { |
|
1080 | elem.addClass('ng-hide'); |
|
1081 | } |
|
1082 | }); |
|
1083 | }); |
|
1084 | } |
|
1085 | ||
1086 | $timeout(function () { |
|
1087 | var unwatch = scope.$watch(attr[directiveName], function (file) { |
|
1088 | var size = resizeParams; |
|
1089 | if (directiveName === 'ngfThumbnail') { |
|
1090 | if (!size) { |
|
1091 | size = {width: elem[0].naturalWidth || elem[0].clientWidth, |
|
1092 | height: elem[0].naturalHeight || elem[0].clientHeight}; |
|
1093 | } |
|
1094 | if (size.width === 0 && window.getComputedStyle) { |
|
1095 | var style = getComputedStyle(elem[0]); |
|
1096 | size = { |
|
1097 | width: parseInt(style.width.slice(0, -2)), |
|
1098 | height: parseInt(style.height.slice(0, -2)) |
|
1099 | }; |
|
1100 | } |
|
1101 | } |
|
1102 | ||
1103 | if (angular.isString(file)) { |
|
1104 | elem.removeClass('ng-hide'); |
|
1105 | if (isBackground) { |
|
1106 | return elem.css('background-image', 'url(\'' + file + '\')'); |
|
1107 | } else { |
|
1108 | return elem.attr('src', file); |
|
1109 | } |
|
1110 | } |
|
1111 | if (file && file.type && file.type.search(getTagType(elem[0])) === 0 && |
|
1112 | (!isBackground || file.type.indexOf('image') === 0)) { |
|
1113 | if (size && Upload.isResizeSupported()) { |
|
1114 | size.resizeIf = function (width, height) { |
|
1115 | return Upload.attrGetter('ngfResizeIf', attr, scope, |
|
1116 | {$width: width, $height: height, $file: file}); |
|
1117 | }; |
|
1118 | Upload.resize(file, size).then( |
|
1119 | function (f) { |
|
1120 | constructDataUrl(f); |
|
1121 | }, function (e) { |
|
1122 | throw e; |
|
1123 | } |
|
1124 | ); |
|
1125 | } else { |
|
1126 | constructDataUrl(file); |
|
1127 | } |
|
1128 | } else { |
|
1129 | elem.addClass('ng-hide'); |
|
1130 | } |
|
1131 | }); |
|
1132 | ||
1133 | scope.$on('$destroy', function () { |
|
1134 | unwatch(); |
|
1135 | }); |
|
1136 | }); |
|
1137 | } |
|
1138 | ||
1139 | ||
1140 | /** @namespace attr.ngfSrc */ |
|
1141 | /** @namespace attr.ngfNoObjectUrl */ |
|
1142 | ngFileUpload.directive('ngfSrc', ['Upload', '$timeout', function (Upload, $timeout) { |
|
1143 | return { |
|
1144 | restrict: 'AE', |
|
1145 | link: function (scope, elem, attr) { |
|
1146 | linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfSrc', |
|
1147 | Upload.attrGetter('ngfResize', attr, scope), false); |
|
1148 | } |
|
1149 | }; |
|
1150 | }]); |
|
1151 | ||
1152 | /** @namespace attr.ngfBackground */ |
|
1153 | /** @namespace attr.ngfNoObjectUrl */ |
|
1154 | ngFileUpload.directive('ngfBackground', ['Upload', '$timeout', function (Upload, $timeout) { |
|
1155 | return { |
|
1156 | restrict: 'AE', |
|
1157 | link: function (scope, elem, attr) { |
|
1158 | linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfBackground', |
|
1159 | Upload.attrGetter('ngfResize', attr, scope), true); |
|
1160 | } |
|
1161 | }; |
|
1162 | }]); |
|
1163 | ||
1164 | /** @namespace attr.ngfThumbnail */ |
|
1165 | /** @namespace attr.ngfAsBackground */ |
|
1166 | /** @namespace attr.ngfSize */ |
|
1167 | /** @namespace attr.ngfNoObjectUrl */ |
|
1168 | ngFileUpload.directive('ngfThumbnail', ['Upload', '$timeout', function (Upload, $timeout) { |
|
1169 | return { |
|
1170 | restrict: 'AE', |
|
1171 | link: function (scope, elem, attr) { |
|
1172 | var size = Upload.attrGetter('ngfSize', attr, scope); |
|
1173 | linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfThumbnail', size, |
|
1174 | Upload.attrGetter('ngfAsBackground', attr, scope)); |
|
1175 | } |
|
1176 | }; |
|
1177 | }]); |
|
1178 | ||
1179 | ngFileUpload.config(['$compileProvider', function ($compileProvider) { |
|
1180 | if ($compileProvider.imgSrcSanitizationWhitelist) $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/); |
|
1181 | if ($compileProvider.aHrefSanitizationWhitelist) $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/); |
|
1182 | }]); |
|
1183 | ||
1184 | ngFileUpload.filter('ngfDataUrl', ['UploadDataUrl', '$sce', function (UploadDataUrl, $sce) { |
|
1185 | return function (file, disallowObjectUrl, trustedUrl) { |
|
1186 | if (angular.isString(file)) { |
|
1187 | return $sce.trustAsResourceUrl(file); |
|
1188 | } |
|
1189 | var src = file && ((disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl); |
|
1190 | if (file && !src) { |
|
1191 | if (!file.$ngfDataUrlFilterInProgress && angular.isObject(file)) { |
|
1192 | file.$ngfDataUrlFilterInProgress = true; |
|
1193 | UploadDataUrl.dataUrl(file, disallowObjectUrl); |
|
1194 | } |
|
1195 | return ''; |
|
1196 | } |
|
1197 | if (file) delete file.$ngfDataUrlFilterInProgress; |
|
1198 | return (file && src ? (trustedUrl ? $sce.trustAsResourceUrl(src) : src) : file) || ''; |
|
1199 | }; |
|
1200 | }]); |
|
1201 | ||
1202 | })(); |
|
1203 | ||
1204 | ngFileUpload.service('UploadValidate', ['UploadDataUrl', '$q', '$timeout', function (UploadDataUrl, $q, $timeout) { |
|
1205 | var upload = UploadDataUrl; |
@@ 1-252 (lines=252) @@ | ||
1 | (function () { |
|
2 | ||
3 | ngFileUpload.service('UploadDataUrl', ['UploadBase', '$timeout', '$q', function (UploadBase, $timeout, $q) { |
|
4 | var upload = UploadBase; |
|
5 | upload.base64DataUrl = function (file) { |
|
6 | if (angular.isArray(file)) { |
|
7 | var d = $q.defer(), count = 0; |
|
8 | angular.forEach(file, function (f) { |
|
9 | upload.dataUrl(f, true)['finally'](function () { |
|
10 | count++; |
|
11 | if (count === file.length) { |
|
12 | var urls = []; |
|
13 | angular.forEach(file, function (ff) { |
|
14 | urls.push(ff.$ngfDataUrl); |
|
15 | }); |
|
16 | d.resolve(urls, file); |
|
17 | } |
|
18 | }); |
|
19 | }); |
|
20 | return d.promise; |
|
21 | } else { |
|
22 | return upload.dataUrl(file, true); |
|
23 | } |
|
24 | }; |
|
25 | upload.dataUrl = function (file, disallowObjectUrl) { |
|
26 | if (!file) return upload.emptyPromise(file, file); |
|
27 | if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { |
|
28 | return upload.emptyPromise(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl, file); |
|
29 | } |
|
30 | var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; |
|
31 | if (p) return p; |
|
32 | ||
33 | var deferred = $q.defer(); |
|
34 | $timeout(function () { |
|
35 | if (window.FileReader && file && |
|
36 | (!window.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && |
|
37 | (!window.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { |
|
38 | //prefer URL.createObjectURL for handling refrences to files of all sizes |
|
39 | //since it doesn´t build a large string in memory |
|
40 | var URL = window.URL || window.webkitURL; |
|
41 | if (URL && URL.createObjectURL && !disallowObjectUrl) { |
|
42 | var url; |
|
43 | try { |
|
44 | url = URL.createObjectURL(file); |
|
45 | } catch (e) { |
|
46 | $timeout(function () { |
|
47 | file.$ngfBlobUrl = ''; |
|
48 | deferred.reject(); |
|
49 | }); |
|
50 | return; |
|
51 | } |
|
52 | $timeout(function () { |
|
53 | file.$ngfBlobUrl = url; |
|
54 | if (url) { |
|
55 | deferred.resolve(url, file); |
|
56 | upload.blobUrls = upload.blobUrls || []; |
|
57 | upload.blobUrlsTotalSize = upload.blobUrlsTotalSize || 0; |
|
58 | upload.blobUrls.push({url: url, size: file.size}); |
|
59 | upload.blobUrlsTotalSize += file.size || 0; |
|
60 | var maxMemory = upload.defaults.blobUrlsMaxMemory || 268435456; |
|
61 | var maxLength = upload.defaults.blobUrlsMaxQueueSize || 200; |
|
62 | while ((upload.blobUrlsTotalSize > maxMemory || upload.blobUrls.length > maxLength) && upload.blobUrls.length > 1) { |
|
63 | var obj = upload.blobUrls.splice(0, 1)[0]; |
|
64 | URL.revokeObjectURL(obj.url); |
|
65 | upload.blobUrlsTotalSize -= obj.size; |
|
66 | } |
|
67 | } |
|
68 | }); |
|
69 | } else { |
|
70 | var fileReader = new FileReader(); |
|
71 | fileReader.onload = function (e) { |
|
72 | $timeout(function () { |
|
73 | file.$ngfDataUrl = e.target.result; |
|
74 | deferred.resolve(e.target.result, file); |
|
75 | $timeout(function () { |
|
76 | delete file.$ngfDataUrl; |
|
77 | }, 1000); |
|
78 | }); |
|
79 | }; |
|
80 | fileReader.onerror = function () { |
|
81 | $timeout(function () { |
|
82 | file.$ngfDataUrl = ''; |
|
83 | deferred.reject(); |
|
84 | }); |
|
85 | }; |
|
86 | fileReader.readAsDataURL(file); |
|
87 | } |
|
88 | } else { |
|
89 | $timeout(function () { |
|
90 | file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; |
|
91 | deferred.reject(); |
|
92 | }); |
|
93 | } |
|
94 | }); |
|
95 | ||
96 | if (disallowObjectUrl) { |
|
97 | p = file.$$ngfDataUrlPromise = deferred.promise; |
|
98 | } else { |
|
99 | p = file.$$ngfBlobUrlPromise = deferred.promise; |
|
100 | } |
|
101 | p['finally'](function () { |
|
102 | delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; |
|
103 | }); |
|
104 | return p; |
|
105 | }; |
|
106 | return upload; |
|
107 | }]); |
|
108 | ||
109 | function getTagType(el) { |
|
110 | if (el.tagName.toLowerCase() === 'img') return 'image'; |
|
111 | if (el.tagName.toLowerCase() === 'audio') return 'audio'; |
|
112 | if (el.tagName.toLowerCase() === 'video') return 'video'; |
|
113 | return /./; |
|
114 | } |
|
115 | ||
116 | function linkFileDirective(Upload, $timeout, scope, elem, attr, directiveName, resizeParams, isBackground) { |
|
117 | function constructDataUrl(file) { |
|
118 | var disallowObjectUrl = Upload.attrGetter('ngfNoObjectUrl', attr, scope); |
|
119 | Upload.dataUrl(file, disallowObjectUrl)['finally'](function () { |
|
120 | $timeout(function () { |
|
121 | var src = (disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl; |
|
122 | if (isBackground) { |
|
123 | elem.css('background-image', 'url(\'' + (src || '') + '\')'); |
|
124 | } else { |
|
125 | elem.attr('src', src); |
|
126 | } |
|
127 | if (src) { |
|
128 | elem.removeClass('ng-hide'); |
|
129 | } else { |
|
130 | elem.addClass('ng-hide'); |
|
131 | } |
|
132 | }); |
|
133 | }); |
|
134 | } |
|
135 | ||
136 | $timeout(function () { |
|
137 | var unwatch = scope.$watch(attr[directiveName], function (file) { |
|
138 | var size = resizeParams; |
|
139 | if (directiveName === 'ngfThumbnail') { |
|
140 | if (!size) { |
|
141 | size = {width: elem[0].naturalWidth || elem[0].clientWidth, |
|
142 | height: elem[0].naturalHeight || elem[0].clientHeight}; |
|
143 | } |
|
144 | if (size.width === 0 && window.getComputedStyle) { |
|
145 | var style = getComputedStyle(elem[0]); |
|
146 | size = { |
|
147 | width: parseInt(style.width.slice(0, -2)), |
|
148 | height: parseInt(style.height.slice(0, -2)) |
|
149 | }; |
|
150 | } |
|
151 | } |
|
152 | ||
153 | if (angular.isString(file)) { |
|
154 | elem.removeClass('ng-hide'); |
|
155 | if (isBackground) { |
|
156 | return elem.css('background-image', 'url(\'' + file + '\')'); |
|
157 | } else { |
|
158 | return elem.attr('src', file); |
|
159 | } |
|
160 | } |
|
161 | if (file && file.type && file.type.search(getTagType(elem[0])) === 0 && |
|
162 | (!isBackground || file.type.indexOf('image') === 0)) { |
|
163 | if (size && Upload.isResizeSupported()) { |
|
164 | size.resizeIf = function (width, height) { |
|
165 | return Upload.attrGetter('ngfResizeIf', attr, scope, |
|
166 | {$width: width, $height: height, $file: file}); |
|
167 | }; |
|
168 | Upload.resize(file, size).then( |
|
169 | function (f) { |
|
170 | constructDataUrl(f); |
|
171 | }, function (e) { |
|
172 | throw e; |
|
173 | } |
|
174 | ); |
|
175 | } else { |
|
176 | constructDataUrl(file); |
|
177 | } |
|
178 | } else { |
|
179 | elem.addClass('ng-hide'); |
|
180 | } |
|
181 | }); |
|
182 | ||
183 | scope.$on('$destroy', function () { |
|
184 | unwatch(); |
|
185 | }); |
|
186 | }); |
|
187 | } |
|
188 | ||
189 | ||
190 | /** @namespace attr.ngfSrc */ |
|
191 | /** @namespace attr.ngfNoObjectUrl */ |
|
192 | ngFileUpload.directive('ngfSrc', ['Upload', '$timeout', function (Upload, $timeout) { |
|
193 | return { |
|
194 | restrict: 'AE', |
|
195 | link: function (scope, elem, attr) { |
|
196 | linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfSrc', |
|
197 | Upload.attrGetter('ngfResize', attr, scope), false); |
|
198 | } |
|
199 | }; |
|
200 | }]); |
|
201 | ||
202 | /** @namespace attr.ngfBackground */ |
|
203 | /** @namespace attr.ngfNoObjectUrl */ |
|
204 | ngFileUpload.directive('ngfBackground', ['Upload', '$timeout', function (Upload, $timeout) { |
|
205 | return { |
|
206 | restrict: 'AE', |
|
207 | link: function (scope, elem, attr) { |
|
208 | linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfBackground', |
|
209 | Upload.attrGetter('ngfResize', attr, scope), true); |
|
210 | } |
|
211 | }; |
|
212 | }]); |
|
213 | ||
214 | /** @namespace attr.ngfThumbnail */ |
|
215 | /** @namespace attr.ngfAsBackground */ |
|
216 | /** @namespace attr.ngfSize */ |
|
217 | /** @namespace attr.ngfNoObjectUrl */ |
|
218 | ngFileUpload.directive('ngfThumbnail', ['Upload', '$timeout', function (Upload, $timeout) { |
|
219 | return { |
|
220 | restrict: 'AE', |
|
221 | link: function (scope, elem, attr) { |
|
222 | var size = Upload.attrGetter('ngfSize', attr, scope); |
|
223 | linkFileDirective(Upload, $timeout, scope, elem, attr, 'ngfThumbnail', size, |
|
224 | Upload.attrGetter('ngfAsBackground', attr, scope)); |
|
225 | } |
|
226 | }; |
|
227 | }]); |
|
228 | ||
229 | ngFileUpload.config(['$compileProvider', function ($compileProvider) { |
|
230 | if ($compileProvider.imgSrcSanitizationWhitelist) $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/); |
|
231 | if ($compileProvider.aHrefSanitizationWhitelist) $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/); |
|
232 | }]); |
|
233 | ||
234 | ngFileUpload.filter('ngfDataUrl', ['UploadDataUrl', '$sce', function (UploadDataUrl, $sce) { |
|
235 | return function (file, disallowObjectUrl, trustedUrl) { |
|
236 | if (angular.isString(file)) { |
|
237 | return $sce.trustAsResourceUrl(file); |
|
238 | } |
|
239 | var src = file && ((disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl) || file.$ngfDataUrl); |
|
240 | if (file && !src) { |
|
241 | if (!file.$ngfDataUrlFilterInProgress && angular.isObject(file)) { |
|
242 | file.$ngfDataUrlFilterInProgress = true; |
|
243 | UploadDataUrl.dataUrl(file, disallowObjectUrl); |
|
244 | } |
|
245 | return ''; |
|
246 | } |
|
247 | if (file) delete file.$ngfDataUrlFilterInProgress; |
|
248 | return (file && src ? (trustedUrl ? $sce.trustAsResourceUrl(src) : src) : file) || ''; |
|
249 | }; |
|
250 | }]); |
|
251 | ||
252 | })(); |
|
253 |