Issues (4542)

js/cropping/main.js (5 issues)

1
(function (factory) {
2
  if (typeof define === 'function' && define.amd) {
3
    define(['jquery'], factory);
4
  } else if (typeof exports === 'object') {
5
    // Node / CommonJS
6
    factory(require('jquery'));
7
  } else {
8
    factory(jQuery);
9
  }
10
})(function ($) {
11
12
  'use strict';
13
14
  var console = window.console || { log: function () {} };
15
16
  function CropAvatar($element) {
17
    this.$container = $element;
18
19
    this.$avatarView = this.$container.find('.avatar-view');
20
    this.$avatar = this.$avatarView.find('img');
21
    this.$avatarModal = this.$container.find('#avatar-modal');
22
    this.$loading = this.$container.find('.loading');
23
24
    this.$avatarForm = this.$avatarModal.find('.avatar-form');
25
    this.$avatarUpload = this.$avatarForm.find('.avatar-upload');
26
    this.$avatarSrc = this.$avatarForm.find('.avatar-src');
27
    this.$avatarData = this.$avatarForm.find('.avatar-data');
28
    this.$avatarInput = this.$avatarForm.find('.avatar-input');
29
    this.$avatarSave = this.$avatarForm.find('.avatar-save');
30
    this.$avatarBtns = this.$avatarForm.find('.avatar-btns');
31
32
    this.$avatarWrapper = this.$avatarModal.find('.avatar-wrapper');
33
    this.$avatarPreview = this.$avatarModal.find('.avatar-preview');
34
35
    this.init();
36
    console.log(this);
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
37
  }
38
39
  CropAvatar.prototype = {
40
    constructor: CropAvatar,
41
42
    support: {
43
      fileList: !!$('<input type="file">').prop('files'),
44
      blobURLs: !!window.URL && URL.createObjectURL,
45
      formData: !!window.FormData
46
    },
47
48
    init: function () {
49
      this.support.datauri = this.support.fileList && this.support.blobURLs;
50
51
      if (!this.support.formData) {
52
        this.initIframe();
53
      }
54
55
      this.initTooltip();
56
      this.initModal();
57
      this.addListener();
58
    },
59
60
    addListener: function () {
61
      this.$avatarView.on('click', $.proxy(this.click, this));
62
      this.$avatarInput.on('change', $.proxy(this.change, this));
63
      this.$avatarForm.on('submit', $.proxy(this.submit, this));
64
      this.$avatarBtns.on('click', $.proxy(this.rotate, this));
65
    },
66
67
    initTooltip: function () {
68
      this.$avatarView.tooltip({
69
        placement: 'bottom'
70
      });
71
    },
72
73
    initModal: function () {
74
      this.$avatarModal.modal({
75
        show: false
76
      });
77
    },
78
79
    initPreview: function () {
80
      var url = this.$avatar.attr('src');
81
82
      this.$avatarPreview.empty().html('<img src="' + url + '">');
83
    },
84
85
    initIframe: function () {
86
      var target = 'upload-iframe-' + (new Date()).getTime(),
87
          $iframe = $('<iframe>').attr({
88
            name: target,
89
            src: ''
90
          }),
91
          _this = this;
92
93
      // Ready ifrmae
94
      $iframe.one('load', function () {
95
96
        // respond response
97
        $iframe.on('load', function () {
98
          var data;
99
100
          try {
101
            data = $(this).contents().find('body').text();
102
          } catch (e) {
103
            console.log(e.message);
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
104
          }
105
106
          if (data) {
107
            try {
108
              data = $.parseJSON(data);
109
            } catch (e) {
110
              console.log(e.message);
111
            }
112
113
            _this.submitDone(data);
114
          } else {
115
            _this.submitFail('Image upload failed!');
116
          }
117
118
          _this.submitEnd();
119
120
        });
121
      });
122
123
      this.$iframe = $iframe;
124
      this.$avatarForm.attr('target', target).after($iframe.hide());
125
    },
126
127
    click: function () {
128
      this.$avatarModal.modal('show');
129
      this.initPreview();
130
    },
131
132
    change: function () {
133
      var files,
134
          file;
135
136
      if (this.support.datauri) {
137
        files = this.$avatarInput.prop('files');
138
139
        if (files.length > 0) {
140
          file = files[0];
141
142
          if (this.isImageFile(file)) {
143
            if (this.url) {
144
              URL.revokeObjectURL(this.url); // Revoke the old one
145
            }
146
147
            this.url = URL.createObjectURL(file);
148
            this.startCropper();
149
          }
150
        }
151
      } else {
152
        file = this.$avatarInput.val();
153
154
        if (this.isImageFile(file)) {
155
          this.syncUpload();
156
        }
157
      }
158
    },
159
160
    submit: function () {
161
      if (!this.$avatarSrc.val() && !this.$avatarInput.val()) {
162
        return false;
163
      }
164
165
      if (this.support.formData) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if this.support.formData is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
166
        this.ajaxUpload();
167
        return false;
168
      }
169
    },
170
171
    rotate: function (e) {
172
      var data;
173
174
      if (this.Aktif) {
175
        data = $(e.target).data();
176
177
        if (data.method) {
178
          this.$img.cropper(data.method, data.option);
179
        }
180
      }
181
    },
182
183
    isImageFile: function (file) {
184
      if (file.type) {
185
        return /^image\/\w+$/.test(file.type);
186
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
187
        return /\.(jpg|jpeg|png|gif)$/.test(file);
188
      }
189
    },
190
191
    startCropper: function () {
192
      var _this = this;
193
194
      if (this.Aktif) {
195
        this.$img.cropper('replace', this.url);
196
      } else {
197
        this.$img = $('<img src="' + this.url + '">');
198
        this.$avatarWrapper.empty().html(this.$img);
199
        this.$img.cropper({
200
          aspectRatio: 1,
201
          preview: this.$avatarPreview.selector,
202
          crop: function (data) {
203
            var json = [
204
                  '{"x":' + data.x,
205
                  '"y":' + data.y,
206
                  '"height":' + data.height,
207
                  '"width":' + data.width,
208
                  '"rotate":' + data.rotate + '}'
209
                ].join();
210
211
            _this.$avatarData.val(json);
212
          }
213
        });
214
215
        this.Aktif = true;
216
      }
217
    },
218
219
    stopCropper: function () {
220
      if (this.Aktif) {
221
        this.$img.cropper('destroy');
222
        this.$img.remove();
223
        this.Aktif = false;
224
      }
225
    },
226
227
    ajaxUpload: function () {
228
      var url = this.$avatarForm.attr('action'),
229
          data = new FormData(this.$avatarForm[0]),
230
          _this = this;
231
232
      $.ajax(url, {
233
        type: 'post',
234
        data: data,
235
        dataType: 'json',
236
        processData: false,
237
        contentType: false,
238
239
        beforeSend: function () {
240
          _this.submitStart();
241
        },
242
243
        success: function (data) {
244
          _this.submitDone(data);
245
        },
246
247
        error: function (XMLHttpRequest, textStatus, errorThrown) {
248
          _this.submitFail(textStatus || errorThrown);
249
        },
250
251
        complete: function () {
252
          _this.submitEnd();
253
        }
254
      });
255
    },
256
257
    syncUpload: function () {
258
      this.$avatarSave.click();
259
    },
260
261
    submitStart: function () {
262
      this.$loading.fadeIn();
263
    },
264
265
    submitDone: function (data) {
266
      console.log(data);
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
267
268
      if ($.isPlainObject(data) && data.state === 200) {
269
        if (data.result) {
270
          this.url = data.result;
271
272
          if (this.support.datauri || this.uploaded) {
273
            this.uploaded = false;
274
            this.cropDone();
275
          } else {
276
            this.uploaded = true;
277
            this.$avatarSrc.val(this.url);
278
            this.startCropper();
279
          }
280
281
          this.$avatarInput.val('');
282
        } else if (data.message) {
283
          this.alert(data.message);
284
        }
285
      } else {
286
        this.alert('Failed to response');
287
      }
288
    },
289
290
    submitFail: function (msg) {
291
      this.alert(msg);
292
    },
293
294
    submitEnd: function () {
295
      this.$loading.fadeOut();
296
    },
297
298
    cropDone: function () {
299
      this.$avatarForm.get(0).reset();
300
      this.$avatar.attr('src', this.url);
301
      this.stopCropper();
302
      this.$avatarModal.modal('hide');
303
    },
304
305
    alert: function (msg) {
306
      var $alert = [
307
            '<div class="alert alert-danger avater-alert">',
308
              '<button type="button" class="close" data-dismiss="alert">&times;</button>',
309
              msg,
310
            '</div>'
311
          ].join('');
312
313
      this.$avatarUpload.after($alert);
314
    }
315
  };
316
317
  $(function () {
318
    return new CropAvatar($('#crop-avatar'));
319
  });
320
321
});
322