compressorjs 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,28 +1,80 @@
1
1
  /*!
2
- * Compressor.js v1.2.0
2
+ * Compressor.js v1.3.0
3
3
  * https://fengyuanchen.github.io/compressorjs
4
4
  *
5
5
  * Copyright 2018-present Chen Fengyuan
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2023-02-25T11:35:56.625Z
8
+ * Date: 2026-04-06T07:12:45.816Z
9
9
  */
10
10
 
11
11
  'use strict';
12
12
 
13
+ function _classCallCheck(a, n) {
14
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
15
+ }
16
+ function _defineProperties(e, r) {
17
+ for (var t = 0; t < r.length; t++) {
18
+ var o = r[t];
19
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
20
+ }
21
+ }
22
+ function _createClass(e, r, t) {
23
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
24
+ writable: !1
25
+ }), e;
26
+ }
27
+ function _defineProperty(e, r, t) {
28
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
29
+ value: t,
30
+ enumerable: !0,
31
+ configurable: !0,
32
+ writable: !0
33
+ }) : e[r] = t, e;
34
+ }
13
35
  function _extends() {
14
- _extends = Object.assign ? Object.assign.bind() : function (target) {
15
- for (var i = 1; i < arguments.length; i++) {
16
- var source = arguments[i];
17
- for (var key in source) {
18
- if (Object.prototype.hasOwnProperty.call(source, key)) {
19
- target[key] = source[key];
20
- }
21
- }
36
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
37
+ for (var e = 1; e < arguments.length; e++) {
38
+ var t = arguments[e];
39
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
22
40
  }
23
- return target;
24
- };
25
- return _extends.apply(this, arguments);
41
+ return n;
42
+ }, _extends.apply(null, arguments);
43
+ }
44
+ function ownKeys(e, r) {
45
+ var t = Object.keys(e);
46
+ if (Object.getOwnPropertySymbols) {
47
+ var o = Object.getOwnPropertySymbols(e);
48
+ r && (o = o.filter(function (r) {
49
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
50
+ })), t.push.apply(t, o);
51
+ }
52
+ return t;
53
+ }
54
+ function _objectSpread2(e) {
55
+ for (var r = 1; r < arguments.length; r++) {
56
+ var t = null != arguments[r] ? arguments[r] : {};
57
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
58
+ _defineProperty(e, r, t[r]);
59
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
60
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
61
+ });
62
+ }
63
+ return e;
64
+ }
65
+ function _toPrimitive(t, r) {
66
+ if ("object" != typeof t || !t) return t;
67
+ var e = t[Symbol.toPrimitive];
68
+ if (void 0 !== e) {
69
+ var i = e.call(t, r || "default");
70
+ if ("object" != typeof i) return i;
71
+ throw new TypeError("@@toPrimitive must return a primitive value.");
72
+ }
73
+ return ("string" === r ? String : Number)(t);
74
+ }
75
+ function _toPropertyKey(t) {
76
+ var i = _toPrimitive(t, "string");
77
+ return "symbol" == typeof i ? i : i + "";
26
78
  }
27
79
 
28
80
  var canvasToBlob = {exports: {}};
@@ -140,7 +192,7 @@ var canvasToBlob = {exports: {}};
140
192
  })(canvasToBlob);
141
193
  var toBlob = canvasToBlob.exports;
142
194
 
143
- var isBlob = value => {
195
+ var isBlob = function isBlob(value) {
144
196
  if (typeof Blob === 'undefined') {
145
197
  return false;
146
198
  }
@@ -273,18 +325,18 @@ var DEFAULTS = {
273
325
  error: null
274
326
  };
275
327
 
276
- const IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
277
- const WINDOW = IS_BROWSER ? window : {};
328
+ var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
329
+ var WINDOW = IS_BROWSER ? window : {};
278
330
 
279
331
  /**
280
332
  * Check if the given value is a positive number.
281
333
  * @param {*} value - The value to check.
282
334
  * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
283
335
  */
284
- const isPositiveNumber = value => value > 0 && value < Infinity;
285
- const {
286
- slice
287
- } = Array.prototype;
336
+ var isPositiveNumber = function isPositiveNumber(value) {
337
+ return value > 0 && value < Infinity;
338
+ };
339
+ var slice = Array.prototype.slice;
288
340
 
289
341
  /**
290
342
  * Convert array-like or iterable object to an array.
@@ -294,7 +346,7 @@ const {
294
346
  function toArray(value) {
295
347
  return Array.from ? Array.from(value) : slice.call(value);
296
348
  }
297
- const REGEXP_IMAGE_TYPE = /^image\/.+$/;
349
+ var REGEXP_IMAGE_TYPE = /^image\/.+$/;
298
350
 
299
351
  /**
300
352
  * Check if the given value is a mime type of image.
@@ -311,15 +363,13 @@ function isImageType(value) {
311
363
  * @returns {boolean} Returns the image extension.
312
364
  */
313
365
  function imageTypeToExtension(value) {
314
- let extension = isImageType(value) ? value.substr(6) : '';
366
+ var extension = isImageType(value) ? value.substr(6) : '';
315
367
  if (extension === 'jpeg') {
316
368
  extension = 'jpg';
317
369
  }
318
- return `.${extension}`;
370
+ return ".".concat(extension);
319
371
  }
320
- const {
321
- fromCharCode
322
- } = String;
372
+ var fromCharCode = String.fromCharCode;
323
373
 
324
374
  /**
325
375
  * Get string from char code in data view.
@@ -329,17 +379,58 @@ const {
329
379
  * @returns {string} The read result.
330
380
  */
331
381
  function getStringFromCharCode(dataView, start, length) {
332
- let str = '';
333
- let i;
382
+ var str = '';
383
+ var i;
334
384
  length += start;
335
385
  for (i = start; i < length; i += 1) {
336
386
  str += fromCharCode(dataView.getUint8(i));
337
387
  }
338
388
  return str;
339
389
  }
340
- const {
341
- btoa
342
- } = WINDOW;
390
+
391
+ /**
392
+ * Check if `canvas.getContext('2d').getImageData` is available,
393
+ * FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode (#137)
394
+ * @link https://github.com/nodeca/pica/blob/master/lib/utils.js
395
+ * @returns {boolean} Returns `true` if it is available, else `false`.
396
+ */
397
+ function isCanvasAvailable() {
398
+ try {
399
+ var canvas = document.createElement('canvas');
400
+ canvas.width = 2;
401
+ canvas.height = 1;
402
+ var context = canvas.getContext('2d');
403
+ if (!context) return false;
404
+
405
+ // Create 2x1 image data containing RGBA values for two pixels
406
+ var imageData = context.createImageData(2, 1);
407
+
408
+ // First pixel: R=12, G=23, B=34, A=255
409
+ imageData.data[0] = 12;
410
+ imageData.data[1] = 23;
411
+ imageData.data[2] = 34;
412
+ imageData.data[3] = 255;
413
+
414
+ // Second pixel: R=45, G=56, B=67, A=255
415
+ imageData.data[4] = 45;
416
+ imageData.data[5] = 56;
417
+ imageData.data[6] = 67;
418
+ imageData.data[7] = 255;
419
+ context.putImageData(imageData, 0, 0);
420
+ var readBack = context.getImageData(0, 0, 2, 1);
421
+
422
+ // Expected pixel data (matching the written values)
423
+ var expected = [12, 23, 34, 255, 45, 56, 67, 255];
424
+
425
+ // Compare element by element to ensure write and read consistency
426
+ return readBack.data.every(function (value, index) {
427
+ return value === expected[index];
428
+ });
429
+ } catch (error) {
430
+ return false;
431
+ }
432
+ }
433
+ var btoa = WINDOW.btoa;
343
434
 
344
435
  /**
345
436
  * Transform array buffer to Data URL.
@@ -348,16 +439,16 @@ const {
348
439
  * @returns {string} The result Data URL.
349
440
  */
350
441
  function arrayBufferToDataURL(arrayBuffer, mimeType) {
351
- const chunks = [];
352
- const chunkSize = 8192;
353
- let uint8 = new Uint8Array(arrayBuffer);
442
+ var chunks = [];
443
+ var chunkSize = 8192;
444
+ var uint8 = new Uint8Array(arrayBuffer);
354
445
  while (uint8.length > 0) {
355
446
  // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
356
447
  // eslint-disable-next-line prefer-spread
357
448
  chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
358
449
  uint8 = uint8.subarray(chunkSize);
359
450
  }
360
- return `data:${mimeType};base64,${btoa(chunks.join(''))}`;
451
+ return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
361
452
  }
362
453
 
363
454
  /**
@@ -366,19 +457,19 @@ function arrayBufferToDataURL(arrayBuffer, mimeType) {
366
457
  * @returns {number} The read orientation value.
367
458
  */
368
459
  function resetAndGetOrientation(arrayBuffer) {
369
- const dataView = new DataView(arrayBuffer);
370
- let orientation;
460
+ var dataView = new DataView(arrayBuffer);
461
+ var orientation;
371
462
 
372
463
  // Ignores range error when the image does not have correct Exif information
373
464
  try {
374
- let littleEndian;
375
- let app1Start;
376
- let ifdStart;
465
+ var littleEndian;
466
+ var app1Start;
467
+ var ifdStart;
377
468
 
378
469
  // Only handle JPEG image (start by 0xFFD8)
379
470
  if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
380
- const length = dataView.byteLength;
381
- let offset = 2;
471
+ var length = dataView.byteLength;
472
+ var offset = 2;
382
473
  while (offset + 1 < length) {
383
474
  if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
384
475
  app1Start = offset;
@@ -388,14 +479,14 @@ function resetAndGetOrientation(arrayBuffer) {
388
479
  }
389
480
  }
390
481
  if (app1Start) {
391
- const exifIDCode = app1Start + 4;
392
- const tiffOffset = app1Start + 10;
482
+ var exifIDCode = app1Start + 4;
483
+ var tiffOffset = app1Start + 10;
393
484
  if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
394
- const endianness = dataView.getUint16(tiffOffset);
485
+ var endianness = dataView.getUint16(tiffOffset);
395
486
  littleEndian = endianness === 0x4949;
396
487
  if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
397
488
  if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
398
- const firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
489
+ var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
399
490
  if (firstIFDOffset >= 0x00000008) {
400
491
  ifdStart = tiffOffset + firstIFDOffset;
401
492
  }
@@ -404,20 +495,20 @@ function resetAndGetOrientation(arrayBuffer) {
404
495
  }
405
496
  }
406
497
  if (ifdStart) {
407
- const length = dataView.getUint16(ifdStart, littleEndian);
408
- let offset;
409
- let i;
410
- for (i = 0; i < length; i += 1) {
411
- offset = ifdStart + i * 12 + 2;
412
- if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
498
+ var _length = dataView.getUint16(ifdStart, littleEndian);
499
+ var _offset;
500
+ var i;
501
+ for (i = 0; i < _length; i += 1) {
502
+ _offset = ifdStart + i * 12 + 2;
503
+ if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) {
413
504
  // 8 is the offset of the current tag's value
414
- offset += 8;
505
+ _offset += 8;
415
506
 
416
507
  // Get the original orientation value
417
- orientation = dataView.getUint16(offset, littleEndian);
508
+ orientation = dataView.getUint16(_offset, littleEndian);
418
509
 
419
510
  // Override the orientation with its default value
420
- dataView.setUint16(offset, 1, littleEndian);
511
+ dataView.setUint16(_offset, 1, littleEndian);
421
512
  break;
422
513
  }
423
514
  }
@@ -434,9 +525,9 @@ function resetAndGetOrientation(arrayBuffer) {
434
525
  * @returns {Object} The parsed result.
435
526
  */
436
527
  function parseOrientation(orientation) {
437
- let rotate = 0;
438
- let scaleX = 1;
439
- let scaleY = 1;
528
+ var rotate = 0;
529
+ var scaleX = 1;
530
+ var scaleY = 1;
440
531
  switch (orientation) {
441
532
  // Flip horizontal
442
533
  case 2:
@@ -476,12 +567,12 @@ function parseOrientation(orientation) {
476
567
  break;
477
568
  }
478
569
  return {
479
- rotate,
480
- scaleX,
481
- scaleY
570
+ rotate: rotate,
571
+ scaleX: scaleX,
572
+ scaleY: scaleY
482
573
  };
483
574
  }
484
- const REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
575
+ var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
485
576
 
486
577
  /**
487
578
  * Normalize decimal number.
@@ -491,7 +582,7 @@ const REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
491
582
  * @returns {number} Returns the normalized number.
492
583
  */
493
584
  function normalizeDecimalNumber(value) {
494
- let times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
585
+ var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
495
586
  return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
496
587
  }
497
588
 
@@ -502,16 +593,14 @@ function normalizeDecimalNumber(value) {
502
593
  * @returns {Object} The result sizes.
503
594
  */
504
595
  function getAdjustedSizes(_ref) {
505
- let {
506
- aspectRatio,
507
- height,
508
- width
509
- } = _ref;
510
- let type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'none';
511
- const isValidWidth = isPositiveNumber(width);
512
- const isValidHeight = isPositiveNumber(height);
596
+ var aspectRatio = _ref.aspectRatio,
597
+ height = _ref.height,
598
+ width = _ref.width;
599
+ var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'none';
600
+ var isValidWidth = isPositiveNumber(width);
601
+ var isValidHeight = isPositiveNumber(height);
513
602
  if (isValidWidth && isValidHeight) {
514
- const adjustedWidth = height * aspectRatio;
603
+ var adjustedWidth = height * aspectRatio;
515
604
  if ((type === 'contain' || type === 'none') && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
516
605
  height = width / aspectRatio;
517
606
  } else {
@@ -523,8 +612,8 @@ function getAdjustedSizes(_ref) {
523
612
  width = height * aspectRatio;
524
613
  }
525
614
  return {
526
- width,
527
- height
615
+ width: width,
616
+ height: height
528
617
  };
529
618
  }
530
619
 
@@ -534,15 +623,13 @@ function getAdjustedSizes(_ref) {
534
623
  * @returns {Array} The read Exif information.
535
624
  */
536
625
  function getExif(arrayBuffer) {
537
- const array = toArray(new Uint8Array(arrayBuffer));
538
- const {
539
- length
540
- } = array;
541
- const segments = [];
542
- let start = 0;
626
+ var array = toArray(new Uint8Array(arrayBuffer));
627
+ var length = array.length;
628
+ var segments = [];
629
+ var start = 0;
543
630
  while (start + 3 < length) {
544
- const value = array[start];
545
- const next = array[start + 1];
631
+ var value = array[start];
632
+ var next = array[start + 1];
546
633
 
547
634
  // SOS (Start of Scan)
548
635
  if (value === 0xFF && next === 0xDA) {
@@ -553,14 +640,14 @@ function getExif(arrayBuffer) {
553
640
  if (value === 0xFF && next === 0xD8) {
554
641
  start += 2;
555
642
  } else {
556
- const offset = array[start + 2] * 256 + array[start + 3];
557
- const end = start + offset + 2;
558
- const segment = array.slice(start, end);
643
+ var offset = array[start + 2] * 256 + array[start + 3];
644
+ var end = start + offset + 2;
645
+ var segment = array.slice(start, end);
559
646
  segments.push(segment);
560
647
  start = end;
561
648
  }
562
649
  }
563
- return segments.reduce((exifArray, current) => {
650
+ return segments.reduce(function (exifArray, current) {
564
651
  if (current[0] === 0xFF && current[1] === 0xE1) {
565
652
  return exifArray.concat(current);
566
653
  }
@@ -575,414 +662,438 @@ function getExif(arrayBuffer) {
575
662
  * @returns {ArrayBuffer} The transformed array buffer.
576
663
  */
577
664
  function insertExif(arrayBuffer, exifArray) {
578
- const array = toArray(new Uint8Array(arrayBuffer));
665
+ var array = toArray(new Uint8Array(arrayBuffer));
579
666
  if (array[2] !== 0xFF || array[3] !== 0xE0) {
580
667
  return arrayBuffer;
581
668
  }
582
- const app0Length = array[4] * 256 + array[5];
583
- const newArrayBuffer = [0xFF, 0xD8].concat(exifArray, array.slice(4 + app0Length));
669
+ var app0Length = array[4] * 256 + array[5];
670
+ var newArrayBuffer = [0xFF, 0xD8].concat(exifArray, array.slice(4 + app0Length));
584
671
  return new Uint8Array(newArrayBuffer);
585
672
  }
586
673
 
587
- const {
588
- ArrayBuffer: ArrayBuffer$1,
589
- FileReader
590
- } = WINDOW;
591
- const URL = WINDOW.URL || WINDOW.webkitURL;
592
- const REGEXP_EXTENSION = /\.\w+$/;
593
- const AnotherCompressor = WINDOW.Compressor;
674
+ var ArrayBuffer$1 = WINDOW.ArrayBuffer,
675
+ FileReader = WINDOW.FileReader;
676
+ var URL = WINDOW.URL || WINDOW.webkitURL;
677
+ var REGEXP_EXTENSION = /\.\w+$/;
678
+ var AnotherCompressor = WINDOW.Compressor;
594
679
 
595
680
  /**
596
681
  * Creates a new image compressor.
597
682
  * @class
598
683
  */
599
- class Compressor {
684
+ var Compressor = /*#__PURE__*/function () {
600
685
  /**
601
686
  * The constructor of Compressor.
602
687
  * @param {File|Blob} file - The target image file for compressing.
603
688
  * @param {Object} [options] - The options for compressing.
604
689
  */
605
- constructor(file, options) {
690
+ function Compressor(file, options) {
691
+ _classCallCheck(this, Compressor);
606
692
  this.file = file;
607
693
  this.exif = [];
608
694
  this.image = new Image();
609
- this.options = {
610
- ...DEFAULTS,
611
- ...options
612
- };
695
+ this.options = _objectSpread2(_objectSpread2({}, DEFAULTS), options);
613
696
  this.aborted = false;
614
697
  this.result = null;
615
698
  this.init();
616
699
  }
617
- init() {
618
- const {
619
- file,
620
- options
621
- } = this;
622
- if (!isBlob(file)) {
623
- this.fail(new Error('The first argument must be a File or Blob object.'));
624
- return;
625
- }
626
- const mimeType = file.type;
627
- if (!isImageType(mimeType)) {
628
- this.fail(new Error('The first argument must be an image File or Blob object.'));
629
- return;
630
- }
631
- if (!URL || !FileReader) {
632
- this.fail(new Error('The current browser does not support image compression.'));
633
- return;
634
- }
635
- if (!ArrayBuffer$1) {
636
- options.checkOrientation = false;
637
- options.retainExif = false;
638
- }
639
- const isJPEGImage = mimeType === 'image/jpeg';
640
- const checkOrientation = isJPEGImage && options.checkOrientation;
641
- const retainExif = isJPEGImage && options.retainExif;
642
- if (URL && !checkOrientation && !retainExif) {
643
- this.load({
644
- url: URL.createObjectURL(file)
645
- });
646
- } else {
647
- const reader = new FileReader();
648
- this.reader = reader;
649
- reader.onload = _ref => {
650
- let {
651
- target
652
- } = _ref;
653
- const {
654
- result
655
- } = target;
656
- const data = {};
657
- let orientation = 1;
658
- if (checkOrientation) {
659
- // Reset the orientation value to its default value 1
660
- // as some iOS browsers will render image with its orientation
661
- orientation = resetAndGetOrientation(result);
662
- if (orientation > 1) {
663
- _extends(data, parseOrientation(orientation));
700
+ return _createClass(Compressor, [{
701
+ key: "init",
702
+ value: function init() {
703
+ var _this = this;
704
+ var file = this.file,
705
+ options = this.options;
706
+ if (!isBlob(file)) {
707
+ this.fail(new Error('The first argument must be a File or Blob object.'));
708
+ return;
709
+ }
710
+ var mimeType = file.type;
711
+ if (!isImageType(mimeType)) {
712
+ this.fail(new Error('The first argument must be an image File or Blob object.'));
713
+ return;
714
+ }
715
+ if (!URL || !FileReader) {
716
+ this.fail(new Error('The current browser does not support image compression.'));
717
+ return;
718
+ }
719
+ if (!ArrayBuffer$1) {
720
+ options.checkOrientation = false;
721
+ options.retainExif = false;
722
+ }
723
+ var isJPEGImage = mimeType === 'image/jpeg';
724
+ var checkOrientation = isJPEGImage && options.checkOrientation;
725
+ var retainExif = isJPEGImage && options.retainExif;
726
+ if (URL && !checkOrientation && !retainExif) {
727
+ this.load({
728
+ url: URL.createObjectURL(file)
729
+ });
730
+ } else {
731
+ var reader = new FileReader();
732
+ this.reader = reader;
733
+ reader.onload = function (_ref) {
734
+ var target = _ref.target;
735
+ var result = target.result;
736
+ var data = {};
737
+ var orientation = 1;
738
+ if (checkOrientation) {
739
+ // Reset the orientation value to its default value 1
740
+ // as some iOS browsers will render image with its orientation
741
+ orientation = resetAndGetOrientation(result);
742
+ if (orientation > 1) {
743
+ _extends(data, parseOrientation(orientation));
744
+ }
664
745
  }
665
- }
666
- if (retainExif) {
667
- this.exif = getExif(result);
668
- }
669
- if (checkOrientation || retainExif) {
670
- if (!URL
746
+ if (retainExif) {
747
+ _this.exif = getExif(result);
748
+ }
749
+ if (checkOrientation || retainExif) {
750
+ if (!URL
671
751
 
672
- // Generate a new URL with the default orientation value 1.
673
- || orientation > 1) {
674
- data.url = arrayBufferToDataURL(result, mimeType);
752
+ // Generate a new URL with the default orientation value 1.
753
+ || orientation > 1) {
754
+ data.url = arrayBufferToDataURL(result, mimeType);
755
+ } else {
756
+ data.url = URL.createObjectURL(file);
757
+ }
675
758
  } else {
676
- data.url = URL.createObjectURL(file);
759
+ data.url = result;
677
760
  }
761
+ _this.load(data);
762
+ };
763
+ reader.onabort = function () {
764
+ _this.fail(new Error('Aborted to read the image with FileReader.'));
765
+ };
766
+ reader.onerror = function () {
767
+ _this.fail(new Error('Failed to read the image with FileReader.'));
768
+ };
769
+ reader.onloadend = function () {
770
+ _this.reader = null;
771
+ };
772
+ if (checkOrientation || retainExif) {
773
+ reader.readAsArrayBuffer(file);
678
774
  } else {
679
- data.url = result;
775
+ reader.readAsDataURL(file);
776
+ }
777
+ }
778
+ }
779
+ }, {
780
+ key: "load",
781
+ value: function load(data) {
782
+ var _this2 = this;
783
+ var file = this.file,
784
+ image = this.image;
785
+ image.onload = function () {
786
+ if (isCanvasAvailable()) {
787
+ _this2.draw(_objectSpread2(_objectSpread2({}, data), {}, {
788
+ naturalWidth: image.naturalWidth,
789
+ naturalHeight: image.naturalHeight
790
+ }));
791
+ } else {
792
+ _this2.done({
793
+ naturalWidth: image.naturalWidth,
794
+ naturalHeight: image.naturalHeight,
795
+ result: null
796
+ });
680
797
  }
681
- this.load(data);
682
- };
683
- reader.onabort = () => {
684
- this.fail(new Error('Aborted to read the image with FileReader.'));
685
798
  };
686
- reader.onerror = () => {
687
- this.fail(new Error('Failed to read the image with FileReader.'));
799
+ image.onabort = function () {
800
+ _this2.fail(new Error('Aborted to load the image.'));
688
801
  };
689
- reader.onloadend = () => {
690
- this.reader = null;
802
+ image.onerror = function () {
803
+ _this2.fail(new Error('Failed to load the image.'));
691
804
  };
692
- if (checkOrientation || retainExif) {
693
- reader.readAsArrayBuffer(file);
694
- } else {
695
- reader.readAsDataURL(file);
696
- }
697
- }
698
- }
699
- load(data) {
700
- const {
701
- file,
702
- image
703
- } = this;
704
- image.onload = () => {
705
- this.draw({
706
- ...data,
707
- naturalWidth: image.naturalWidth,
708
- naturalHeight: image.naturalHeight
709
- });
710
- };
711
- image.onabort = () => {
712
- this.fail(new Error('Aborted to load the image.'));
713
- };
714
- image.onerror = () => {
715
- this.fail(new Error('Failed to load the image.'));
716
- };
717
805
 
718
- // Match all browsers that use WebKit as the layout engine in iOS devices,
719
- // such as Safari for iOS, Chrome for iOS, and in-app browsers.
720
- if (WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent)) {
721
- // Fix the `The operation is insecure` error (#57)
722
- image.crossOrigin = 'anonymous';
723
- }
724
- image.alt = file.name;
725
- image.src = data.url;
726
- }
727
- draw(_ref2) {
728
- let {
729
- naturalWidth,
730
- naturalHeight,
731
- rotate = 0,
732
- scaleX = 1,
733
- scaleY = 1
734
- } = _ref2;
735
- const {
736
- file,
737
- image,
738
- options
739
- } = this;
740
- const canvas = document.createElement('canvas');
741
- const context = canvas.getContext('2d');
742
- const is90DegreesRotated = Math.abs(rotate) % 180 === 90;
743
- const resizable = (options.resize === 'contain' || options.resize === 'cover') && isPositiveNumber(options.width) && isPositiveNumber(options.height);
744
- let maxWidth = Math.max(options.maxWidth, 0) || Infinity;
745
- let maxHeight = Math.max(options.maxHeight, 0) || Infinity;
746
- let minWidth = Math.max(options.minWidth, 0) || 0;
747
- let minHeight = Math.max(options.minHeight, 0) || 0;
748
- let aspectRatio = naturalWidth / naturalHeight;
749
- let {
750
- width,
751
- height
752
- } = options;
753
- if (is90DegreesRotated) {
754
- [maxWidth, maxHeight] = [maxHeight, maxWidth];
755
- [minWidth, minHeight] = [minHeight, minWidth];
756
- [width, height] = [height, width];
757
- }
758
- if (resizable) {
759
- aspectRatio = width / height;
760
- }
761
- ({
762
- width: maxWidth,
763
- height: maxHeight
764
- } = getAdjustedSizes({
765
- aspectRatio,
766
- width: maxWidth,
767
- height: maxHeight
768
- }, 'contain'));
769
- ({
770
- width: minWidth,
771
- height: minHeight
772
- } = getAdjustedSizes({
773
- aspectRatio,
774
- width: minWidth,
775
- height: minHeight
776
- }, 'cover'));
777
- if (resizable) {
778
- ({
779
- width,
780
- height
781
- } = getAdjustedSizes({
782
- aspectRatio,
783
- width,
784
- height
785
- }, options.resize));
786
- } else {
787
- ({
788
- width = naturalWidth,
789
- height = naturalHeight
790
- } = getAdjustedSizes({
791
- aspectRatio,
792
- width,
793
- height
794
- }));
795
- }
796
- width = Math.floor(normalizeDecimalNumber(Math.min(Math.max(width, minWidth), maxWidth)));
797
- height = Math.floor(normalizeDecimalNumber(Math.min(Math.max(height, minHeight), maxHeight)));
798
- const destX = -width / 2;
799
- const destY = -height / 2;
800
- const destWidth = width;
801
- const destHeight = height;
802
- const params = [];
803
- if (resizable) {
804
- let srcX = 0;
805
- let srcY = 0;
806
- let srcWidth = naturalWidth;
807
- let srcHeight = naturalHeight;
808
- ({
809
- width: srcWidth,
810
- height: srcHeight
811
- } = getAdjustedSizes({
812
- aspectRatio,
813
- width: naturalWidth,
814
- height: naturalHeight
815
- }, {
816
- contain: 'cover',
817
- cover: 'contain'
818
- }[options.resize]));
819
- srcX = (naturalWidth - srcWidth) / 2;
820
- srcY = (naturalHeight - srcHeight) / 2;
821
- params.push(srcX, srcY, srcWidth, srcHeight);
822
- }
823
- params.push(destX, destY, destWidth, destHeight);
824
- if (is90DegreesRotated) {
825
- [width, height] = [height, width];
826
- }
827
- canvas.width = width;
828
- canvas.height = height;
829
- if (!isImageType(options.mimeType)) {
830
- options.mimeType = file.type;
806
+ // Match all browsers that use WebKit as the layout engine in iOS devices,
807
+ // such as Safari for iOS, Chrome for iOS, and in-app browsers.
808
+ if (WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent)) {
809
+ // Fix the `The operation is insecure` error (#57)
810
+ image.crossOrigin = 'anonymous';
811
+ }
812
+ image.alt = file.name;
813
+ image.src = data.url;
831
814
  }
832
- let fillStyle = 'transparent';
815
+ }, {
816
+ key: "draw",
817
+ value: function draw(_ref2) {
818
+ var _this3 = this;
819
+ var naturalWidth = _ref2.naturalWidth,
820
+ naturalHeight = _ref2.naturalHeight,
821
+ _ref2$rotate = _ref2.rotate,
822
+ rotate = _ref2$rotate === void 0 ? 0 : _ref2$rotate,
823
+ _ref2$scaleX = _ref2.scaleX,
824
+ scaleX = _ref2$scaleX === void 0 ? 1 : _ref2$scaleX,
825
+ _ref2$scaleY = _ref2.scaleY,
826
+ scaleY = _ref2$scaleY === void 0 ? 1 : _ref2$scaleY;
827
+ var file = this.file,
828
+ image = this.image,
829
+ options = this.options;
830
+ var canvas = document.createElement('canvas');
831
+ var context = canvas.getContext('2d');
832
+ var is90DegreesRotated = Math.abs(rotate) % 180 === 90;
833
+ var resizable = (options.resize === 'contain' || options.resize === 'cover') && isPositiveNumber(options.width) && isPositiveNumber(options.height);
834
+ var maxWidth = Math.max(options.maxWidth, 0) || Infinity;
835
+ var maxHeight = Math.max(options.maxHeight, 0) || Infinity;
836
+ var minWidth = Math.max(options.minWidth, 0) || 0;
837
+ var minHeight = Math.max(options.minHeight, 0) || 0;
838
+ var aspectRatio = naturalWidth / naturalHeight;
839
+ var width = options.width,
840
+ height = options.height;
841
+ if (is90DegreesRotated) {
842
+ var _ref3 = [maxHeight, maxWidth];
843
+ maxWidth = _ref3[0];
844
+ maxHeight = _ref3[1];
845
+ var _ref4 = [minHeight, minWidth];
846
+ minWidth = _ref4[0];
847
+ minHeight = _ref4[1];
848
+ var _ref5 = [height, width];
849
+ width = _ref5[0];
850
+ height = _ref5[1];
851
+ }
852
+ if (resizable) {
853
+ aspectRatio = width / height;
854
+ }
855
+ var _getAdjustedSizes = getAdjustedSizes({
856
+ aspectRatio: aspectRatio,
857
+ width: maxWidth,
858
+ height: maxHeight
859
+ }, 'contain');
860
+ maxWidth = _getAdjustedSizes.width;
861
+ maxHeight = _getAdjustedSizes.height;
862
+ var _getAdjustedSizes2 = getAdjustedSizes({
863
+ aspectRatio: aspectRatio,
864
+ width: minWidth,
865
+ height: minHeight
866
+ }, 'cover');
867
+ minWidth = _getAdjustedSizes2.width;
868
+ minHeight = _getAdjustedSizes2.height;
869
+ if (resizable) {
870
+ var _getAdjustedSizes3 = getAdjustedSizes({
871
+ aspectRatio: aspectRatio,
872
+ width: width,
873
+ height: height
874
+ }, options.resize);
875
+ width = _getAdjustedSizes3.width;
876
+ height = _getAdjustedSizes3.height;
877
+ } else {
878
+ var _getAdjustedSizes4 = getAdjustedSizes({
879
+ aspectRatio: aspectRatio,
880
+ width: width,
881
+ height: height
882
+ });
883
+ var _getAdjustedSizes4$wi = _getAdjustedSizes4.width;
884
+ width = _getAdjustedSizes4$wi === void 0 ? naturalWidth : _getAdjustedSizes4$wi;
885
+ var _getAdjustedSizes4$he = _getAdjustedSizes4.height;
886
+ height = _getAdjustedSizes4$he === void 0 ? naturalHeight : _getAdjustedSizes4$he;
887
+ }
888
+ width = Math.floor(normalizeDecimalNumber(Math.min(Math.max(width, minWidth), maxWidth)));
889
+ height = Math.floor(normalizeDecimalNumber(Math.min(Math.max(height, minHeight), maxHeight)));
890
+ var destX = -width / 2;
891
+ var destY = -height / 2;
892
+ var destWidth = width;
893
+ var destHeight = height;
894
+ var params = [];
895
+ if (resizable) {
896
+ var srcX = 0;
897
+ var srcY = 0;
898
+ var srcWidth = naturalWidth;
899
+ var srcHeight = naturalHeight;
900
+ var _getAdjustedSizes5 = getAdjustedSizes({
901
+ aspectRatio: aspectRatio,
902
+ width: naturalWidth,
903
+ height: naturalHeight
904
+ }, {
905
+ contain: 'cover',
906
+ cover: 'contain'
907
+ }[options.resize]);
908
+ srcWidth = _getAdjustedSizes5.width;
909
+ srcHeight = _getAdjustedSizes5.height;
910
+ srcX = (naturalWidth - srcWidth) / 2;
911
+ srcY = (naturalHeight - srcHeight) / 2;
912
+ params.push(srcX, srcY, srcWidth, srcHeight);
913
+ }
914
+ params.push(destX, destY, destWidth, destHeight);
915
+ if (is90DegreesRotated) {
916
+ var _ref6 = [height, width];
917
+ width = _ref6[0];
918
+ height = _ref6[1];
919
+ }
920
+ canvas.width = width;
921
+ canvas.height = height;
922
+ if (!isImageType(options.mimeType)) {
923
+ options.mimeType = file.type;
924
+ }
925
+ var fillStyle = 'transparent';
833
926
 
834
- // Converts PNG files over the `convertSize` to JPEGs.
835
- if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
836
- options.mimeType = 'image/jpeg';
837
- }
838
- const isJPEGImage = options.mimeType === 'image/jpeg';
839
- if (isJPEGImage) {
840
- fillStyle = '#fff';
841
- }
927
+ // Converts PNG files over the `convertSize` to JPEGs.
928
+ if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
929
+ options.mimeType = 'image/jpeg';
930
+ }
931
+ var isJPEGImage = options.mimeType === 'image/jpeg';
932
+ if (isJPEGImage) {
933
+ fillStyle = '#fff';
934
+ }
842
935
 
843
- // Override the default fill color (#000, black)
844
- context.fillStyle = fillStyle;
845
- context.fillRect(0, 0, width, height);
846
- if (options.beforeDraw) {
847
- options.beforeDraw.call(this, context, canvas);
848
- }
849
- if (this.aborted) {
850
- return;
851
- }
852
- context.save();
853
- context.translate(width / 2, height / 2);
854
- context.rotate(rotate * Math.PI / 180);
855
- context.scale(scaleX, scaleY);
856
- context.drawImage(image, ...params);
857
- context.restore();
858
- if (options.drew) {
859
- options.drew.call(this, context, canvas);
860
- }
861
- if (this.aborted) {
862
- return;
863
- }
864
- const callback = blob => {
865
- if (!this.aborted) {
866
- const done = result => this.done({
867
- naturalWidth,
868
- naturalHeight,
869
- result
870
- });
871
- if (blob && isJPEGImage && options.retainExif && this.exif && this.exif.length > 0) {
872
- const next = arrayBuffer => done(toBlob(arrayBufferToDataURL(insertExif(arrayBuffer, this.exif), options.mimeType)));
873
- if (blob.arrayBuffer) {
874
- blob.arrayBuffer().then(next).catch(() => {
875
- this.fail(new Error('Failed to read the compressed image with Blob.arrayBuffer().'));
936
+ // Override the default fill color (#000, black)
937
+ context.fillStyle = fillStyle;
938
+ context.fillRect(0, 0, width, height);
939
+ if (options.beforeDraw) {
940
+ options.beforeDraw.call(this, context, canvas);
941
+ }
942
+ if (this.aborted) {
943
+ return;
944
+ }
945
+ context.save();
946
+ context.translate(width / 2, height / 2);
947
+ context.rotate(rotate * Math.PI / 180);
948
+ context.scale(scaleX, scaleY);
949
+ context.drawImage.apply(context, [image].concat(params));
950
+ context.restore();
951
+ if (options.drew) {
952
+ options.drew.call(this, context, canvas);
953
+ }
954
+ if (this.aborted) {
955
+ return;
956
+ }
957
+ var callback = function callback(blob) {
958
+ if (!_this3.aborted) {
959
+ var done = function done(result) {
960
+ return _this3.done({
961
+ naturalWidth: naturalWidth,
962
+ naturalHeight: naturalHeight,
963
+ result: result
876
964
  });
877
- } else {
878
- const reader = new FileReader();
879
- this.reader = reader;
880
- reader.onload = _ref3 => {
881
- let {
882
- target
883
- } = _ref3;
884
- next(target.result);
885
- };
886
- reader.onabort = () => {
887
- this.fail(new Error('Aborted to read the compressed image with FileReader.'));
888
- };
889
- reader.onerror = () => {
890
- this.fail(new Error('Failed to read the compressed image with FileReader.'));
891
- };
892
- reader.onloadend = () => {
893
- this.reader = null;
965
+ };
966
+ if (blob && isJPEGImage && options.retainExif && _this3.exif && _this3.exif.length > 0) {
967
+ var next = function next(arrayBuffer) {
968
+ return done(toBlob(arrayBufferToDataURL(insertExif(arrayBuffer, _this3.exif), options.mimeType)));
894
969
  };
895
- reader.readAsArrayBuffer(blob);
970
+ if (blob.arrayBuffer) {
971
+ blob.arrayBuffer().then(next).catch(function () {
972
+ _this3.fail(new Error('Failed to read the compressed image with Blob.arrayBuffer().'));
973
+ });
974
+ } else {
975
+ var reader = new FileReader();
976
+ _this3.reader = reader;
977
+ reader.onload = function (_ref7) {
978
+ var target = _ref7.target;
979
+ next(target.result);
980
+ };
981
+ reader.onabort = function () {
982
+ _this3.fail(new Error('Aborted to read the compressed image with FileReader.'));
983
+ };
984
+ reader.onerror = function () {
985
+ _this3.fail(new Error('Failed to read the compressed image with FileReader.'));
986
+ };
987
+ reader.onloadend = function () {
988
+ _this3.reader = null;
989
+ };
990
+ reader.readAsArrayBuffer(blob);
991
+ }
992
+ } else {
993
+ done(blob);
896
994
  }
897
- } else {
898
- done(blob);
899
995
  }
996
+ };
997
+ if (canvas.toBlob) {
998
+ canvas.toBlob(callback, options.mimeType, options.quality);
999
+ } else {
1000
+ callback(toBlob(canvas.toDataURL(options.mimeType, options.quality)));
900
1001
  }
901
- };
902
- if (canvas.toBlob) {
903
- canvas.toBlob(callback, options.mimeType, options.quality);
904
- } else {
905
- callback(toBlob(canvas.toDataURL(options.mimeType, options.quality)));
906
- }
907
- }
908
- done(_ref4) {
909
- let {
910
- naturalWidth,
911
- naturalHeight,
912
- result
913
- } = _ref4;
914
- const {
915
- file,
916
- image,
917
- options
918
- } = this;
919
- if (URL && image.src.indexOf('blob:') === 0) {
920
- URL.revokeObjectURL(image.src);
921
1002
  }
922
- if (result) {
923
- // Returns original file if the result is greater than it and without size related options
924
- if (options.strict && !options.retainExif && result.size > file.size && options.mimeType === file.type && !(options.width > naturalWidth || options.height > naturalHeight || options.minWidth > naturalWidth || options.minHeight > naturalHeight || options.maxWidth < naturalWidth || options.maxHeight < naturalHeight)) {
925
- result = file;
926
- } else {
927
- const date = new Date();
928
- result.lastModified = date.getTime();
929
- result.lastModifiedDate = date;
930
- result.name = file.name;
931
-
932
- // Convert the extension to match its type
933
- if (result.name && result.type !== file.type) {
934
- result.name = result.name.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1003
+ }, {
1004
+ key: "done",
1005
+ value: function done(_ref8) {
1006
+ var naturalWidth = _ref8.naturalWidth,
1007
+ naturalHeight = _ref8.naturalHeight,
1008
+ result = _ref8.result;
1009
+ var file = this.file,
1010
+ image = this.image,
1011
+ options = this.options;
1012
+ if (URL && image.src.indexOf('blob:') === 0) {
1013
+ URL.revokeObjectURL(image.src);
1014
+ }
1015
+ if (result) {
1016
+ // Returns original file if the result is greater than it and without size related options
1017
+ if (options.strict && !options.retainExif && result.size > file.size && options.mimeType === file.type && !(options.width > naturalWidth || options.height > naturalHeight || options.minWidth > naturalWidth || options.minHeight > naturalHeight || options.maxWidth < naturalWidth || options.maxHeight < naturalHeight)) {
1018
+ result = file;
1019
+ } else {
1020
+ var fileName = file.name;
1021
+
1022
+ // Convert the extension to match its type
1023
+ if (fileName && result.type !== file.type) {
1024
+ fileName = fileName.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1025
+ }
1026
+ try {
1027
+ // Convert the resulting Blob object into a File object for modern browsers.
1028
+ result = new File([result], fileName, {
1029
+ type: result.type
1030
+ });
1031
+ } catch (error) {
1032
+ // Fallback to Blob if the File constructor is not supported.
1033
+ var date = new Date();
1034
+ result.name = fileName;
1035
+
1036
+ // The last modified date is not accurate, but it's better than nothing.
1037
+ result.lastModified = date.getTime();
1038
+ result.lastModifiedDate = date;
1039
+ }
935
1040
  }
1041
+ } else {
1042
+ // Returns original file if the result is null in some cases.
1043
+ result = file;
1044
+ }
1045
+ this.result = result;
1046
+ if (options.success) {
1047
+ options.success.call(this, result);
936
1048
  }
937
- } else {
938
- // Returns original file if the result is null in some cases.
939
- result = file;
940
- }
941
- this.result = result;
942
- if (options.success) {
943
- options.success.call(this, result);
944
- }
945
- }
946
- fail(err) {
947
- const {
948
- options
949
- } = this;
950
- if (options.error) {
951
- options.error.call(this, err);
952
- } else {
953
- throw err;
954
1049
  }
955
- }
956
- abort() {
957
- if (!this.aborted) {
958
- this.aborted = true;
959
- if (this.reader) {
960
- this.reader.abort();
961
- } else if (!this.image.complete) {
962
- this.image.onload = null;
963
- this.image.onabort();
1050
+ }, {
1051
+ key: "fail",
1052
+ value: function fail(err) {
1053
+ var options = this.options;
1054
+ if (options.error) {
1055
+ options.error.call(this, err);
964
1056
  } else {
965
- this.fail(new Error('The compression process has been aborted.'));
1057
+ throw err;
1058
+ }
1059
+ }
1060
+ }, {
1061
+ key: "abort",
1062
+ value: function abort() {
1063
+ if (!this.aborted) {
1064
+ this.aborted = true;
1065
+ if (this.reader) {
1066
+ this.reader.abort();
1067
+ } else if (!this.image.complete) {
1068
+ this.image.onload = null;
1069
+ this.image.onabort();
1070
+ } else {
1071
+ this.fail(new Error('The compression process has been aborted.'));
1072
+ }
966
1073
  }
967
1074
  }
968
- }
969
1075
 
970
- /**
971
- * Get the no conflict compressor class.
972
- * @returns {Compressor} The compressor class.
973
- */
974
- static noConflict() {
975
- window.Compressor = AnotherCompressor;
976
- return Compressor;
977
- }
1076
+ /**
1077
+ * Get the no conflict compressor class.
1078
+ * @returns {Compressor} The compressor class.
1079
+ */
1080
+ }], [{
1081
+ key: "noConflict",
1082
+ value: function noConflict() {
1083
+ window.Compressor = AnotherCompressor;
1084
+ return Compressor;
1085
+ }
978
1086
 
979
- /**
980
- * Change the default options.
981
- * @param {Object} options - The new default options.
982
- */
983
- static setDefaults(options) {
984
- _extends(DEFAULTS, options);
985
- }
986
- }
1087
+ /**
1088
+ * Change the default options.
1089
+ * @param {Object} options - The new default options.
1090
+ */
1091
+ }, {
1092
+ key: "setDefaults",
1093
+ value: function setDefaults(options) {
1094
+ _extends(DEFAULTS, options);
1095
+ }
1096
+ }]);
1097
+ }();
987
1098
 
988
1099
  module.exports = Compressor;