viewerjs 1.9.2 → 1.10.3

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Viewer.js
2
2
 
3
- [![Build Status](https://img.shields.io/travis/fengyuanchen/viewerjs.svg)](https://travis-ci.org/fengyuanchen/viewerjs) [![Downloads](https://img.shields.io/npm/dm/viewerjs.svg)](https://www.npmjs.com/package/viewerjs) [![Version](https://img.shields.io/npm/v/viewerjs.svg)](https://www.npmjs.com/package/viewerjs) [![Gzip Size](https://img.shields.io/bundlephobia/minzip/viewerjs.svg)](https://unpkg.com/viewerjs/dist/viewer.common.js) [![Dependencies](https://img.shields.io/david/fengyuanchen/viewerjs.svg)](https://www.npmjs.com/package/viewerjs)
3
+ [![Downloads](https://img.shields.io/npm/dm/viewerjs.svg)](https://www.npmjs.com/package/viewerjs) [![Version](https://img.shields.io/npm/v/viewerjs.svg)](https://www.npmjs.com/package/viewerjs) [![Gzip Size](https://img.shields.io/bundlephobia/minzip/viewerjs.svg)](https://unpkg.com/viewerjs/dist/viewer.common.js)
4
4
 
5
5
  > JavaScript image viewer.
6
6
 
@@ -36,7 +36,7 @@
36
36
  - Supports keyboard
37
37
  - Cross-browser support
38
38
 
39
- ## Main
39
+ ## Main files
40
40
 
41
41
  ```text
42
42
  dist/
@@ -206,8 +206,8 @@ new Viewer(image, {
206
206
  - `{ key: String }`: customize the size of the button.
207
207
  - `{ key: Function }`: customize the click handler of the button.
208
208
  - `{ key: { show: Boolean | Number, size: String, click: Function }`: customize each property of the button.
209
- - Available keys: "zoomIn", "zoomOut", "oneToOne", "reset", "prev", "play", "next", "rotateLeft", "rotateRight", "flipHorizontal" and "flipVertical".
210
- - Available sizes: "small", "medium" (default) and "large".
209
+ - Available built-in keys: "zoomIn", "zoomOut", "oneToOne", "reset", "prev", "play", "next", "rotateLeft", "rotateRight", "flipHorizontal", "flipVertical".
210
+ - Available built-in sizes: "small", "medium" (default) and "large".
211
211
 
212
212
  Specify the visibility and layout of the toolbar its buttons.
213
213
 
@@ -234,6 +234,8 @@ new Viewer(image, {
234
234
  });
235
235
  ```
236
236
 
237
+ > see more for [custom toolbar](docs/examples/custom-toolbar.html).
238
+
237
239
  ### className
238
240
 
239
241
  - Type: `String`
@@ -272,7 +274,7 @@ new Viewer(image, {
272
274
 
273
275
  ### fullscreen
274
276
 
275
- - Type: `Boolean`
277
+ - Type: `Boolean` or [`FullscreenOptions`](https://developer.mozilla.org/en-US/docs/Web/API/FullscreenOptions)
276
278
  - Default: `true`
277
279
 
278
280
  Enable to request full screen when play.
@@ -838,7 +840,7 @@ viewer.zoomTo(1); // Zoom to natural size (100%)
838
840
  ### play([fullscreen])
839
841
 
840
842
  - **fullscreen** (optional):
841
- - Type: `Boolean`
843
+ - Type: `Boolean` or [`FullscreenOptions`](https://developer.mozilla.org/en-US/docs/Web/API/FullscreenOptions)
842
844
  - Default: `false`
843
845
  - Indicate if request fullscreen or not.
844
846
 
@@ -868,7 +870,7 @@ Show the current ratio of the image by percentage.
868
870
 
869
871
  ### toggle()
870
872
 
871
- Toggle the image size between its natural size and initial size.
873
+ Toggle the image size between its current size and natural size.
872
874
 
873
875
  > Used by the [`toggleOnDblclick`](#toggleOnDblclick) option.
874
876
 
@@ -1,11 +1,11 @@
1
1
  /*!
2
- * Viewer.js v1.9.2
2
+ * Viewer.js v1.10.3
3
3
  * https://fengyuanchen.github.io/viewerjs
4
4
  *
5
5
  * Copyright 2015-present Chen Fengyuan
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2021-05-29T03:50:07.891Z
8
+ * Date: 2022-02-02T05:15:01.702Z
9
9
  */
10
10
 
11
11
  'use strict';
@@ -15,14 +15,9 @@ function ownKeys(object, enumerableOnly) {
15
15
 
16
16
  if (Object.getOwnPropertySymbols) {
17
17
  var symbols = Object.getOwnPropertySymbols(object);
18
-
19
- if (enumerableOnly) {
20
- symbols = symbols.filter(function (sym) {
21
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
22
- });
23
- }
24
-
25
- keys.push.apply(keys, symbols);
18
+ enumerableOnly && (symbols = symbols.filter(function (sym) {
19
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
20
+ })), keys.push.apply(keys, symbols);
26
21
  }
27
22
 
28
23
  return keys;
@@ -30,19 +25,12 @@ function ownKeys(object, enumerableOnly) {
30
25
 
31
26
  function _objectSpread2(target) {
32
27
  for (var i = 1; i < arguments.length; i++) {
33
- var source = arguments[i] != null ? arguments[i] : {};
34
-
35
- if (i % 2) {
36
- ownKeys(Object(source), true).forEach(function (key) {
37
- _defineProperty(target, key, source[key]);
38
- });
39
- } else if (Object.getOwnPropertyDescriptors) {
40
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
41
- } else {
42
- ownKeys(Object(source)).forEach(function (key) {
43
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
44
- });
45
- }
28
+ var source = null != arguments[i] ? arguments[i] : {};
29
+ i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
30
+ _defineProperty(target, key, source[key]);
31
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
32
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
33
+ });
46
34
  }
47
35
 
48
36
  return target;
@@ -51,17 +39,11 @@ function _objectSpread2(target) {
51
39
  function _typeof(obj) {
52
40
  "@babel/helpers - typeof";
53
41
 
54
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
55
- _typeof = function (obj) {
56
- return typeof obj;
57
- };
58
- } else {
59
- _typeof = function (obj) {
60
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
61
- };
62
- }
63
-
64
- return _typeof(obj);
42
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
43
+ return typeof obj;
44
+ } : function (obj) {
45
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
46
+ }, _typeof(obj);
65
47
  }
66
48
 
67
49
  function _classCallCheck(instance, Constructor) {
@@ -83,6 +65,9 @@ function _defineProperties(target, props) {
83
65
  function _createClass(Constructor, protoProps, staticProps) {
84
66
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
85
67
  if (staticProps) _defineProperties(Constructor, staticProps);
68
+ Object.defineProperty(Constructor, "prototype", {
69
+ writable: false
70
+ });
86
71
  return Constructor;
87
72
  }
88
73
 
@@ -153,7 +138,8 @@ var DEFAULTS = {
153
138
 
154
139
  /**
155
140
  * Enable to request fullscreen when play.
156
- * @type {boolean}
141
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/FullscreenOptions}
142
+ * @type {boolean|FullscreenOptions}
157
143
  */
158
144
  fullscreen: true,
159
145
 
@@ -373,6 +359,7 @@ var EVENT_DRAG_START = 'dragstart';
373
359
  var EVENT_FOCUSIN = 'focusin';
374
360
  var EVENT_KEY_DOWN = 'keydown';
375
361
  var EVENT_LOAD = 'load';
362
+ var EVENT_ERROR = 'error';
376
363
  var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';
377
364
  var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';
378
365
  var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';
@@ -489,15 +476,15 @@ function forEach(data, callback) {
489
476
  if (Array.isArray(data) || isNumber(data.length)
490
477
  /* array-like */
491
478
  ) {
492
- var length = data.length;
493
- var i;
479
+ var length = data.length;
480
+ var i;
494
481
 
495
- for (i = 0; i < length; i += 1) {
496
- if (callback.call(data, data[i], i, data) === false) {
497
- break;
498
- }
482
+ for (i = 0; i < length; i += 1) {
483
+ if (callback.call(data, data[i], i, data) === false) {
484
+ break;
499
485
  }
500
- } else if (isObject(data)) {
486
+ }
487
+ } else if (isObject(data)) {
501
488
  Object.keys(data).forEach(function (key) {
502
489
  callback.call(data, data[key], key, data);
503
490
  });
@@ -1122,13 +1109,17 @@ var render = {
1122
1109
  this.items = items;
1123
1110
  forEach(items, function (item) {
1124
1111
  var image = item.firstElementChild;
1112
+ var onLoad;
1113
+ var onError;
1125
1114
  setData(image, 'filled', true);
1126
1115
 
1127
1116
  if (options.loading) {
1128
1117
  addClass(item, CLASS_LOADING);
1129
1118
  }
1130
1119
 
1131
- addListener(image, EVENT_LOAD, function (event) {
1120
+ addListener(image, EVENT_LOAD, onLoad = function onLoad(event) {
1121
+ removeListener(image, EVENT_ERROR, onError);
1122
+
1132
1123
  if (options.loading) {
1133
1124
  removeClass(item, CLASS_LOADING);
1134
1125
  }
@@ -1137,6 +1128,15 @@ var render = {
1137
1128
  }, {
1138
1129
  once: true
1139
1130
  });
1131
+ addListener(image, EVENT_ERROR, onError = function onError() {
1132
+ removeListener(image, EVENT_LOAD, onLoad);
1133
+
1134
+ if (options.loading) {
1135
+ removeClass(item, CLASS_LOADING);
1136
+ }
1137
+ }, {
1138
+ once: true
1139
+ });
1140
1140
  });
1141
1141
 
1142
1142
  if (options.transition) {
@@ -1147,16 +1147,23 @@ var render = {
1147
1147
  });
1148
1148
  }
1149
1149
  },
1150
- renderList: function renderList(index) {
1151
- var i = index || this.index;
1152
- var width = this.items[i].offsetWidth || 30;
1153
- var outerWidth = width + 1; // 1 pixel of `margin-left` width
1154
- // Place the active item in the center of the screen
1150
+ renderList: function renderList() {
1151
+ var index = this.index;
1152
+ var item = this.items[index];
1153
+
1154
+ if (!item) {
1155
+ return;
1156
+ }
1157
+
1158
+ var next = item.nextElementSibling;
1159
+ var gutter = parseInt(window.getComputedStyle(next || item).marginLeft, 10);
1160
+ var offsetWidth = item.offsetWidth;
1161
+ var outerWidth = offsetWidth + gutter; // Place the active item in the center of the screen
1155
1162
 
1156
1163
  setStyle(this.list, assign({
1157
- width: outerWidth * this.length
1164
+ width: outerWidth * this.length - gutter
1158
1165
  }, getTransforms({
1159
- translateX: (this.viewerData.width - width) / 2 - outerWidth * i
1166
+ translateX: (this.viewerData.width - offsetWidth) / 2 - outerWidth * index
1160
1167
  })));
1161
1168
  },
1162
1169
  resetList: function resetList() {
@@ -1206,6 +1213,7 @@ var render = {
1206
1213
  y: top,
1207
1214
  width: width,
1208
1215
  height: height,
1216
+ oldRatio: 1,
1209
1217
  ratio: width / naturalWidth,
1210
1218
  aspectRatio: aspectRatio,
1211
1219
  naturalWidth: naturalWidth,
@@ -1431,9 +1439,10 @@ var handlers = {
1431
1439
  // Cancel the emulated double click when the native dblclick event was triggered.
1432
1440
  if (IS_TOUCH_DEVICE && event.isTrusted) {
1433
1441
  clearTimeout(this.doubleClickImageTimeout);
1434
- }
1442
+ } // XXX: No pageX/Y properties in custom event, fallback to the original event.
1435
1443
 
1436
- this.toggle();
1444
+
1445
+ this.toggle(event.isTrusted ? event : event.detail && event.detail.originalEvent);
1437
1446
  }
1438
1447
  },
1439
1448
  load: function load() {
@@ -1455,7 +1464,7 @@ var handlers = {
1455
1464
  removeClass(this.canvas, CLASS_LOADING);
1456
1465
  }
1457
1466
 
1458
- image.style.cssText = 'height:0;' + "margin-left:".concat(viewerData.width / 2, "px;") + "margin-top:".concat(viewerData.height / 2, "px;") + 'max-width:none!important;' + 'position:absolute;' + 'width:0;';
1467
+ image.style.cssText = 'height:0;' + "margin-left:".concat(viewerData.width / 2, "px;") + "margin-top:".concat(viewerData.height / 2, "px;") + 'max-width:none!important;' + 'position:relative;' + 'width:0;';
1459
1468
  this.initImage(function () {
1460
1469
  toggleClass(image, CLASS_MOVE, options.movable);
1461
1470
  toggleClass(image, CLASS_TRANSITION, options.transition);
@@ -1700,7 +1709,9 @@ var handlers = {
1700
1709
  this.imageClicked = false; // This timeout will be cleared later when a native dblclick event is triggering
1701
1710
 
1702
1711
  this.doubleClickImageTimeout = setTimeout(function () {
1703
- dispatchEvent(_this2.image, EVENT_DBLCLICK);
1712
+ dispatchEvent(_this2.image, EVENT_DBLCLICK, {
1713
+ originalEvent: event
1714
+ });
1704
1715
  }, 50);
1705
1716
  } else {
1706
1717
  this.imageClicked = true; // The default timing of a double click in Windows is 500 ms
@@ -1715,7 +1726,9 @@ var handlers = {
1715
1726
  if (options.backdrop && options.backdrop !== 'static' && event.target === this.canvas) {
1716
1727
  // This timeout will be cleared later when a native click event is triggering
1717
1728
  this.clickCanvasTimeout = setTimeout(function () {
1718
- dispatchEvent(_this2.canvas, EVENT_CLICK);
1729
+ dispatchEvent(_this2.canvas, EVENT_CLICK, {
1730
+ originalEvent: event
1731
+ });
1719
1732
  }, 50);
1720
1733
  }
1721
1734
  }
@@ -1943,7 +1956,7 @@ var methods = {
1943
1956
  addListener(image, EVENT_TRANSITION_END, onImageTransitionEnd, {
1944
1957
  once: true
1945
1958
  });
1946
- this.zoomTo(0, false, false, true);
1959
+ this.zoomTo(0, false, null, true);
1947
1960
  } else {
1948
1961
  onImageTransitionEnd();
1949
1962
  }
@@ -2012,8 +2025,12 @@ var methods = {
2012
2025
  }
2013
2026
 
2014
2027
  var activeItem = this.items[this.index];
2015
- removeClass(activeItem, CLASS_ACTIVE);
2016
- activeItem.removeAttribute('aria-selected');
2028
+
2029
+ if (activeItem) {
2030
+ removeClass(activeItem, CLASS_ACTIVE);
2031
+ activeItem.removeAttribute('aria-selected');
2032
+ }
2033
+
2017
2034
  addClass(item, CLASS_ACTIVE);
2018
2035
  item.setAttribute('aria-selected', true);
2019
2036
 
@@ -2045,6 +2062,7 @@ var methods = {
2045
2062
  };
2046
2063
 
2047
2064
  var onLoad;
2065
+ var onError;
2048
2066
  addListener(element, EVENT_VIEWED, onViewed, {
2049
2067
  once: true
2050
2068
  });
@@ -2073,7 +2091,27 @@ var methods = {
2073
2091
  if (image.complete) {
2074
2092
  this.load();
2075
2093
  } else {
2076
- addListener(image, EVENT_LOAD, onLoad = this.load.bind(this), {
2094
+ addListener(image, EVENT_LOAD, onLoad = function onLoad() {
2095
+ removeListener(image, EVENT_ERROR, onError);
2096
+
2097
+ _this2.load();
2098
+ }, {
2099
+ once: true
2100
+ });
2101
+ addListener(image, EVENT_ERROR, onError = function onError() {
2102
+ removeListener(image, EVENT_LOAD, onLoad);
2103
+
2104
+ if (_this2.timeout) {
2105
+ clearTimeout(_this2.timeout);
2106
+ _this2.timeout = false;
2107
+ }
2108
+
2109
+ removeClass(image, CLASS_INVISIBLE);
2110
+
2111
+ if (options.loading) {
2112
+ removeClass(_this2.canvas, CLASS_LOADING);
2113
+ }
2114
+ }, {
2077
2115
  once: true
2078
2116
  });
2079
2117
 
@@ -2444,15 +2482,31 @@ var methods = {
2444
2482
  ratio = Math.min(Math.max(ratio, minZoomRatio), maxZoomRatio);
2445
2483
  }
2446
2484
 
2447
- if (_originalEvent && options.zoomRatio >= 0.055 && ratio > 0.95 && ratio < 1.05) {
2448
- ratio = 1;
2485
+ if (_originalEvent) {
2486
+ switch (_originalEvent.type) {
2487
+ case 'wheel':
2488
+ if (options.zoomRatio >= 0.055 && ratio > 0.95 && ratio < 1.05) {
2489
+ ratio = 1;
2490
+ }
2491
+
2492
+ break;
2493
+
2494
+ case 'pointermove':
2495
+ case 'touchmove':
2496
+ case 'mousemove':
2497
+ if (ratio > 0.99 && ratio < 1.01) {
2498
+ ratio = 1;
2499
+ }
2500
+
2501
+ break;
2502
+ }
2449
2503
  }
2450
2504
 
2451
2505
  var newWidth = naturalWidth * ratio;
2452
2506
  var newHeight = naturalHeight * ratio;
2453
2507
  var offsetWidth = newWidth - width;
2454
2508
  var offsetHeight = newHeight - height;
2455
- var oldRatio = width / naturalWidth;
2509
+ var oldRatio = imageData.ratio;
2456
2510
 
2457
2511
  if (isFunction(options.zoom)) {
2458
2512
  addListener(element, EVENT_ZOOM, options.zoom, {
@@ -2472,7 +2526,7 @@ var methods = {
2472
2526
 
2473
2527
  if (_originalEvent) {
2474
2528
  var offset = getOffset(this.viewer);
2475
- var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
2529
+ var center = pointers && Object.keys(pointers).length > 0 ? getPointersCenter(pointers) : {
2476
2530
  pageX: _originalEvent.pageX,
2477
2531
  pageY: _originalEvent.pageY
2478
2532
  }; // Zoom from the triggering point of the event
@@ -2489,6 +2543,7 @@ var methods = {
2489
2543
  imageData.top = imageData.y;
2490
2544
  imageData.width = newWidth;
2491
2545
  imageData.height = newHeight;
2546
+ imageData.oldRatio = oldRatio;
2492
2547
  imageData.ratio = ratio;
2493
2548
  this.renderImage(function () {
2494
2549
  _this6.zooming = false;
@@ -2518,7 +2573,7 @@ var methods = {
2518
2573
 
2519
2574
  /**
2520
2575
  * Play the images
2521
- * @param {boolean} [fullscreen=false] - Indicate if request fullscreen or not.
2576
+ * @param {boolean|FullscreenOptions} [fullscreen=false] - Indicate if request fullscreen or not.
2522
2577
  * @returns {Viewer} this
2523
2578
  */
2524
2579
  play: function play() {
@@ -2552,7 +2607,7 @@ var methods = {
2552
2607
  this.onLoadWhenPlay = onLoad;
2553
2608
 
2554
2609
  if (fullscreen) {
2555
- this.requestFullscreen();
2610
+ this.requestFullscreen(fullscreen);
2556
2611
  }
2557
2612
 
2558
2613
  addClass(player, CLASS_SHOW);
@@ -2797,12 +2852,19 @@ var methods = {
2797
2852
  }, 1000);
2798
2853
  return this;
2799
2854
  },
2800
- // Toggle the image size between its natural size and initial size
2855
+
2856
+ /**
2857
+ * Toggle the image size between its current size and natural size
2858
+ * @param {Event} [_originalEvent=null] - The original event if any.
2859
+ * @returns {Viewer} this
2860
+ */
2801
2861
  toggle: function toggle() {
2862
+ var _originalEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
2863
+
2802
2864
  if (this.imageData.ratio === 1) {
2803
- this.zoomTo(this.initialImageData.ratio, true);
2865
+ this.zoomTo(this.imageData.oldRatio, true, _originalEvent);
2804
2866
  } else {
2805
- this.zoomTo(1, true);
2867
+ this.zoomTo(1, true, _originalEvent);
2806
2868
  }
2807
2869
 
2808
2870
  return this;
@@ -3064,14 +3126,19 @@ var others = {
3064
3126
  });
3065
3127
  }
3066
3128
  },
3067
- requestFullscreen: function requestFullscreen() {
3129
+ requestFullscreen: function requestFullscreen(options) {
3068
3130
  var document = this.element.ownerDocument;
3069
3131
 
3070
3132
  if (this.fulled && !(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement)) {
3071
3133
  var documentElement = document.documentElement; // Element.requestFullscreen()
3072
3134
 
3073
3135
  if (documentElement.requestFullscreen) {
3074
- documentElement.requestFullscreen();
3136
+ // Avoid TypeError when convert `options` to dictionary
3137
+ if (isPlainObject(options)) {
3138
+ documentElement.requestFullscreen(options);
3139
+ } else {
3140
+ documentElement.requestFullscreen();
3141
+ }
3075
3142
  } else if (documentElement.webkitRequestFullscreen) {
3076
3143
  documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
3077
3144
  } else if (documentElement.mozRequestFullScreen) {