nexus site path corrected
[portal.git] / ecomp-portal-FE / client / app / directives / image-upload / image-upload.directive.js
1 /*-
2  * ================================================================================
3  * eCOMP Portal
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ================================================================================
19  */
20
21 'use strict';
22
23 angular.module('ecompApp').directive('imageUpload', function factory($q) {
24     var imageMimeRgx = /^image\/[a-zA-Z0-9]*$/;
25
26     var URL = window.URL || window.webkitURL;
27
28     var getResizeArea = function () {
29         var resizeAreaId = 'fileupload-resize-area';
30
31         var resizeArea = document.getElementById(resizeAreaId);
32
33         if (!resizeArea) {
34             resizeArea = document.createElement('canvas');
35             resizeArea.id = resizeAreaId;
36             resizeArea.style.visibility = 'hidden';
37             document.body.appendChild(resizeArea);
38         }
39
40         return resizeArea;
41     };
42
43     var resizeImage = function (origImage, options) {
44         var maxHeight = options.resizeMaxHeight || 300;
45         var maxWidth = options.resizeMaxWidth || 250;
46         var quality = options.resizeQuality || 0.7;
47         var type = options.resizeType || 'image/jpg';
48
49         var canvas = getResizeArea();
50
51         var height = origImage.height;
52         var width = origImage.width;
53
54         //image redraw starting points
55         var x0, y0;
56
57         // calculate the width and height, constraining the proportions
58         if (width > height) {
59             if (width > maxWidth) {
60                 height = Math.round(height *= maxWidth / width);
61                 width = maxWidth;
62
63                 x0 = 0;
64                 y0 = Math.round((maxHeight - height)/2);
65             }else{
66                 maxHeight = height;
67                 maxWidth = width;
68                 x0 = 0;
69                 y0 = 0;
70             }
71         } else {
72             if (height > maxHeight) {
73                 width = Math.round(width *= maxHeight / height);
74                 height = maxHeight;
75
76                 x0 = Math.round((maxWidth - width)/2);
77                 y0 = 0;
78             }else{
79                 maxHeight = height;
80                 maxWidth = width;
81                 x0 = 0;
82                 y0 = 0;
83             }
84         }
85
86         canvas.width = maxWidth;
87         canvas.height = maxHeight;
88
89         //draw image on canvas
90         var ctx = canvas.getContext("2d");
91
92         //set background color
93         if(options.backgroundColor){
94             ctx.fillStyle = options.backgroundColor;
95             ctx.fillRect(0,0,maxWidth,maxHeight);
96         }
97
98
99         ctx.drawImage(origImage, x0, y0, width, height);
100
101         // get the data from canvas as 70% jpg (or specified type).
102         return canvas.toDataURL(type, quality);
103     };
104
105     var createImage = function(url, callback) {
106         var image = new Image();
107         image.onload = function() {
108             callback(image);
109         };
110         image.src = url;
111     };
112
113     var fileToDataURL = function (file) {
114         var deferred = $q.defer();
115         var reader = new FileReader();
116         reader.onload = function (e) {
117             deferred.resolve(e.target.result);
118         };
119         reader.readAsDataURL(file);
120         return deferred.promise;
121     };
122
123     return {
124         restrict: 'A',
125         require: '^form',
126         scope: {
127             image: '=imageUpload',
128             resizeMaxHeight: '@?imageUploadResizeMaxHeight',
129             resizeMaxWidth: '@?imageUploadResizeMaxWidth',
130             resizeQuality: '@?imageUploadResizeQuality',
131             resizeType: '@?imageUploadResizeType',
132             imageApi: '=?imageUploadApi',
133             backgroundColor: '@?imageUploadBackgroundColor'
134         },
135         compile: function compile(tElement, tAttrs, transclude) {
136             return function postLink(scope, iElement, iAttrs, formCtrl) {
137                 var doResizing = function(imageResult, callback) {
138                     createImage(imageResult.url, function(image) {
139                         var dataURL = resizeImage(image, scope);
140                         imageResult.resized = {
141                             dataURL: dataURL,
142                             type: dataURL.match(/:(.+\/.+);/)[1]
143                         };
144                         callback(imageResult);
145                     });
146                 };
147
148                 var applyScope = function(imageResult) {
149                     scope.$apply(function() {
150                         //console.log(imageResult);
151                         if(iAttrs.multiple)
152                             scope.image.push(imageResult);
153                         else
154                             scope.image = imageResult;
155                     });
156                 };
157
158                 iElement.bind('change', function (evt) {
159                     //when multiple always return an array of images
160                     if(iAttrs.multiple)
161                         scope.image = [];
162
163                     var files = evt.target.files;
164                     for(var i = 0; i < files.length; i++) {
165                         setInputValidity(files[i]);
166
167                         //create a result object for each file in files
168                         var imageResult = {
169                             file: files[i],
170                             url: URL.createObjectURL(files[i])
171                         };
172
173                         fileToDataURL(files[i]).then(function (dataURL) {
174                             imageResult.dataURL = dataURL;
175                         });
176
177                         if(scope.resizeMaxHeight || scope.resizeMaxWidth) { //resize image
178                             doResizing(imageResult, function(imageResult) {
179                                 applyScope(imageResult);
180                             });
181                         }
182                         else { //no resizing
183                             applyScope(imageResult);
184                         }
185                     }
186                 });
187
188                 //API for otter actions
189                 scope.imageApi = scope.imageApi || {};
190                 scope.imageApi.clearFile = () => {
191                     iElement[0].value = "";
192                     setInputValidity();
193                 };
194
195
196                 let setInputValidity = file => {
197                     //if form validation supported
198
199                     if(formCtrl && iAttrs.name && formCtrl[iAttrs.name]){
200                         formCtrl[iAttrs.name].$setDirty();
201                         if(file && file.type && !imageMimeRgx.test(file.type)){
202                             //set form invalid
203                             formCtrl[iAttrs.name].$setValidity('mimeType', false);
204                             applyScope();
205                             return;
206                         }
207                         if(file && file.size && file.size > 1000000){
208                             //set form invalid
209                             formCtrl[iAttrs.name].$setValidity('imageSize', false);
210                             applyScope();
211                             return;
212                         }
213                         //set valid
214                         formCtrl[iAttrs.name].$setValidity('mimeType', true);
215                         formCtrl[iAttrs.name].$setValidity('imageSize', true);
216                     }
217
218                 }
219             }
220         }
221     }
222 });