viewerjs 1.13.0 → 1.14.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,11 +1,11 @@
1
1
  /*!
2
- * Viewer.js v1.13.0
2
+ * Viewer.js v1.14.0
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: 2026-09-06T10:39:44.170Z
8
+ * Date: 2026-09-12T12:12:29.730Z
9
9
  */
10
10
 
11
11
  'use strict';
@@ -242,7 +242,10 @@ var DEFAULTS = {
242
242
  zoomOnGesture: true,
243
243
  /**
244
244
  * Enable to zoom the image by wheeling mouse.
245
- * @type {boolean}
245
+ * Set to a modifier key name (`ctrl`, `shift`, `alt`, `meta`), or a
246
+ * combination joined with `+` (e.g. `ctrl+shift`), to only zoom when
247
+ * the given modifier key(s) are held down while wheeling.
248
+ * @type {boolean | string}
246
249
  */
247
250
  zoomOnWheel: true,
248
251
  /**
@@ -250,6 +253,16 @@ var DEFAULTS = {
250
253
  * @type {boolean}
251
254
  */
252
255
  slideOnTouch: true,
256
+ /**
257
+ * Enable to slide to the next or previous image by wheeling mouse.
258
+ * Set to a modifier key name (`ctrl`, `shift`, `alt`, `meta`), or a
259
+ * combination joined with `+` (e.g. `ctrl+shift`), to only slide when
260
+ * the given modifier key(s) are held down while wheeling.
261
+ * Takes effect over the navbar, and also over the rest of the viewer
262
+ * when `zoomOnWheel` doesn't take effect for the wheel event.
263
+ * @type {boolean | string}
264
+ */
265
+ slideOnWheel: true,
253
266
  /**
254
267
  * Indicate if toggle the image size between its natural size
255
268
  * and initial size when double click on the image or not.
@@ -316,10 +329,11 @@ var DEFAULTS = {
316
329
  zoom: null,
317
330
  zoomed: null,
318
331
  play: null,
332
+ playing: null,
319
333
  stop: null
320
334
  };
321
335
 
322
- var TEMPLATE = '<div class="viewer-container" tabindex="-1" touch-action="none">' + '<div class="viewer-canvas"></div>' + '<div class="viewer-magnifier" aria-hidden="true">' + '<img class="viewer-magnifier-image" alt="">' + '</div>' + '<div class="viewer-navigation">' + '<div class="viewer-prev" data-viewer-action="prev" role="button" aria-label="Previous"></div>' + '<div class="viewer-next" data-viewer-action="next" role="button" aria-label="Next"></div>' + '</div>' + '<div class="viewer-footer">' + '<div class="viewer-title"></div>' + '<div class="viewer-toolbar"></div>' + '<div class="viewer-navbar">' + '<ul class="viewer-list" role="navigation"></ul>' + '</div>' + '</div>' + '<div class="viewer-tooltip" role="alert" aria-hidden="true"></div>' + '<div class="viewer-button" data-viewer-action="mix" role="button"></div>' + '<div class="viewer-player"></div>' + '</div>';
336
+ var TEMPLATE = '<div class="viewer-container" tabindex="-1" touch-action="none">' + '<div class="viewer-canvas"></div>' + '<div class="viewer-magnifier" aria-hidden="true">' + '<img class="viewer-magnifier-image" alt="">' + '</div>' + '<div class="viewer-navigation" aria-hidden="true">' + '<div class="viewer-prev" data-viewer-action="prev" role="button" aria-label="Previous"></div>' + '<div class="viewer-next" data-viewer-action="next" role="button" aria-label="Next"></div>' + '</div>' + '<div class="viewer-footer" aria-hidden="true">' + '<div class="viewer-title" aria-hidden="true"></div>' + '<div class="viewer-toolbar" aria-hidden="true"></div>' + '<div class="viewer-navbar" aria-hidden="true">' + '<ul class="viewer-list" role="navigation"></ul>' + '</div>' + '</div>' + '<div class="viewer-tooltip" role="alert" aria-hidden="true"></div>' + '<div class="viewer-button" data-viewer-action="mix" role="button" aria-hidden="true"></div>' + '<div class="viewer-player" aria-hidden="true"></div>' + '</div>';
323
337
 
324
338
  var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
325
339
  var WINDOW = IS_BROWSER ? window : {};
@@ -391,6 +405,7 @@ var EVENT_SCALED = 'scaled';
391
405
  var EVENT_ZOOM = 'zoom';
392
406
  var EVENT_ZOOMED = 'zoomed';
393
407
  var EVENT_PLAY = 'play';
408
+ var EVENT_PLAYING = 'playing';
394
409
  var EVENT_STOP = 'stop';
395
410
 
396
411
  // Data keys
@@ -410,6 +425,30 @@ var BUTTONS = ['zoom-in', 'zoom-out', 'one-to-one', 'reset', 'prev', 'play', 'ne
410
425
  function isString(value) {
411
426
  return typeof value === 'string';
412
427
  }
428
+ var MODIFIER_KEY_PROPERTIES = {
429
+ ctrl: 'ctrlKey',
430
+ shift: 'shiftKey',
431
+ alt: 'altKey',
432
+ meta: 'metaKey'
433
+ };
434
+
435
+ /**
436
+ * Check if a wheel option (`zoomOnWheel` or `slideOnWheel`) takes effect for the given wheel event.
437
+ * @param {boolean | string} option - The option value.
438
+ * @param {WheelEvent} event - The wheel event.
439
+ * @returns {boolean} Returns `true` if the option takes effect for the event, else `false`.
440
+ */
441
+ function isWheelActionEnabled(option, event) {
442
+ if (!option) {
443
+ return false;
444
+ }
445
+ if (option === true) {
446
+ return true;
447
+ }
448
+ return isString(option) && option.split('+').every(function (key) {
449
+ return event[MODIFIER_KEY_PROPERTIES[key.trim().toLowerCase()]];
450
+ });
451
+ }
413
452
 
414
453
  /**
415
454
  * Check if the given value is not a number.
@@ -1078,6 +1117,9 @@ var render = {
1078
1117
  var items = [];
1079
1118
  var navbarOptions = isPlainObject(options.navbar) ? options.navbar : {};
1080
1119
  var probe = document.createElement('li');
1120
+ if (!this.containerData) {
1121
+ this.initContainer();
1122
+ }
1081
1123
  list.appendChild(probe);
1082
1124
  var itemWidth = probe.offsetWidth + parseInt(window.getComputedStyle(probe).marginLeft, 10);
1083
1125
  list.removeChild(probe);
@@ -1332,7 +1374,7 @@ var events = {
1332
1374
  addListener(document, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));
1333
1375
  addListener(document, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));
1334
1376
  addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
1335
- if (options.zoomable && options.zoomOnWheel) {
1377
+ if (options.zoomable && options.zoomOnWheel || options.slideOnWheel) {
1336
1378
  addListener(viewer, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
1337
1379
  passive: false,
1338
1380
  capture: true
@@ -1362,7 +1404,7 @@ var events = {
1362
1404
  removeListener(document, EVENT_POINTER_UP, this.onPointerUp);
1363
1405
  removeListener(document, EVENT_KEY_DOWN, this.onKeyDown);
1364
1406
  removeListener(window, EVENT_RESIZE, this.onResize);
1365
- if (options.zoomable && options.zoomOnWheel) {
1407
+ if (options.zoomable && options.zoomOnWheel || options.slideOnWheel) {
1366
1408
  removeListener(viewer, EVENT_WHEEL, this.onWheel, {
1367
1409
  passive: false,
1368
1410
  capture: true
@@ -1394,6 +1436,7 @@ var handlers = {
1394
1436
  if (IS_TOUCH_DEVICE && event.isTrusted && target === this.canvas) {
1395
1437
  clearTimeout(this.clickCanvasTimeout);
1396
1438
  }
1439
+ this.actionEvent = event;
1397
1440
  switch (action) {
1398
1441
  case 'mix':
1399
1442
  if (this.played) {
@@ -1464,7 +1507,8 @@ var handlers = {
1464
1507
  }
1465
1508
 
1466
1509
  // XXX: No pageX/Y properties in custom event, fallback to the original event.
1467
- this.toggle(event.isTrusted ? event : event.detail && event.detail.originalEvent);
1510
+ this.actionEvent = event.isTrusted ? event : event.detail && event.detail.originalEvent;
1511
+ this.toggle();
1468
1512
  }
1469
1513
  },
1470
1514
  load: function load() {
@@ -1500,10 +1544,12 @@ var handlers = {
1500
1544
  dispatchEvent(element, EVENT_VIEWED, {
1501
1545
  originalImage: _this.images[index],
1502
1546
  index: index,
1503
- image: image
1547
+ image: image,
1548
+ originalEvent: _this.viewOriginalEvent || null
1504
1549
  }, {
1505
1550
  cancelable: false
1506
1551
  });
1552
+ _this.viewOriginalEvent = null;
1507
1553
  });
1508
1554
  });
1509
1555
  },
@@ -1543,6 +1589,7 @@ var handlers = {
1543
1589
  return;
1544
1590
  }
1545
1591
  var keyCode = event.keyCode || event.which || event.charCode;
1592
+ this.actionEvent = event;
1546
1593
  switch (keyCode) {
1547
1594
  // Enter
1548
1595
  case 13:
@@ -1868,6 +1915,8 @@ var handlers = {
1868
1915
  },
1869
1916
  wheel: function wheel(event) {
1870
1917
  var _this4 = this;
1918
+ var options = this.options,
1919
+ navbar = this.navbar;
1871
1920
  if (!this.viewed) {
1872
1921
  return;
1873
1922
  }
@@ -1876,7 +1925,7 @@ var handlers = {
1876
1925
  return;
1877
1926
  }
1878
1927
 
1879
- // Limit wheel speed to prevent zoom too fast
1928
+ // Limit wheel speed to prevent zoom or slide too fast
1880
1929
  if (this.wheeling) {
1881
1930
  return;
1882
1931
  }
@@ -1884,7 +1933,6 @@ var handlers = {
1884
1933
  setTimeout(function () {
1885
1934
  _this4.wheeling = false;
1886
1935
  }, 50);
1887
- var ratio = Number(this.options.zoomRatio) || 0.1;
1888
1936
  var delta = 1;
1889
1937
  if (event.deltaY) {
1890
1938
  delta = event.deltaY > 0 ? 1 : -1;
@@ -1893,7 +1941,24 @@ var handlers = {
1893
1941
  } else if (event.detail) {
1894
1942
  delta = event.detail > 0 ? 1 : -1;
1895
1943
  }
1896
- this.zoom(-delta * ratio, true, null, event);
1944
+
1945
+ // Wheeling over the navbar never zooms, only slides
1946
+ var overNavbar = navbar && navbar.contains(event.target);
1947
+ var zoomable = !overNavbar && options.zoomable && isWheelActionEnabled(options.zoomOnWheel, event);
1948
+ if (zoomable) {
1949
+ var ratio = Number(options.zoomRatio) || 0.1;
1950
+ this.actionEvent = event;
1951
+ this.zoom(-delta * ratio, true);
1952
+ return;
1953
+ }
1954
+ if (isWheelActionEnabled(options.slideOnWheel, event)) {
1955
+ this.actionEvent = event;
1956
+ if (delta > 0) {
1957
+ this.next(options.loop);
1958
+ } else if (delta < 0) {
1959
+ this.prev(options.loop);
1960
+ }
1961
+ }
1897
1962
  },
1898
1963
  gesture: function gesture(event) {
1899
1964
  var options = this.options;
@@ -1915,11 +1980,13 @@ var handlers = {
1915
1980
  var degree = rotation - (this.gestureRotation || 0);
1916
1981
  this.gestureScale = scale;
1917
1982
  if (options.zoomable && options.zoomOnGesture && ratio !== 1) {
1918
- this.zoom(ratio >= 1 ? ratio - 1 : 1 - 1 / ratio, false, null, event);
1983
+ this.actionEvent = event;
1984
+ this.zoom(ratio >= 1 ? ratio - 1 : 1 - 1 / ratio);
1919
1985
  }
1920
1986
  if (options.rotatable && options.rotateOnGesture && isNumber(rotation)) {
1921
1987
  this.gestureRotation = rotation;
1922
1988
  if (degree !== 0) {
1989
+ this.actionEvent = event;
1923
1990
  this.rotate(degree);
1924
1991
  }
1925
1992
  }
@@ -1953,12 +2020,17 @@ var methods = {
1953
2020
  }
1954
2021
  return this;
1955
2022
  }
2023
+ var originalEvent = this.actionEvent || this.showOriginalEvent || this.viewOriginalEvent || null;
2024
+ this.actionEvent = null;
2025
+ this.showOriginalEvent = originalEvent;
1956
2026
  if (isFunction(options.show)) {
1957
2027
  addListener(element, EVENT_SHOW, options.show, {
1958
2028
  once: true
1959
2029
  });
1960
2030
  }
1961
- if (dispatchEvent(element, EVENT_SHOW) === false || !this.ready) {
2031
+ if (dispatchEvent(element, EVENT_SHOW, {
2032
+ originalEvent: originalEvent
2033
+ }) === false || !this.ready) {
1962
2034
  return this;
1963
2035
  }
1964
2036
  if (this.hiding) {
@@ -2007,12 +2079,17 @@ var methods = {
2007
2079
  if (options.inline || this.hiding || !(this.isShown || this.showing)) {
2008
2080
  return this;
2009
2081
  }
2082
+ var originalEvent = this.actionEvent || this.hideOriginalEvent || null;
2083
+ this.actionEvent = null;
2084
+ this.hideOriginalEvent = originalEvent;
2010
2085
  if (isFunction(options.hide)) {
2011
2086
  addListener(element, EVENT_HIDE, options.hide, {
2012
2087
  once: true
2013
2088
  });
2014
2089
  }
2015
- if (dispatchEvent(element, EVENT_HIDE) === false || this.destroyed) {
2090
+ if (dispatchEvent(element, EVENT_HIDE, {
2091
+ originalEvent: originalEvent
2092
+ }) === false || this.destroyed) {
2016
2093
  return this;
2017
2094
  }
2018
2095
  if (this.showing) {
@@ -2063,7 +2140,7 @@ var methods = {
2063
2140
  addListener(image, EVENT_TRANSITION_END, onImageTransitionEnd, {
2064
2141
  once: true
2065
2142
  });
2066
- this.zoomTo(0, false, null, null, true);
2143
+ this.zoomTo(0, false, null, true);
2067
2144
  } else {
2068
2145
  onImageTransitionEnd();
2069
2146
  }
@@ -2085,6 +2162,9 @@ var methods = {
2085
2162
  if (this.hiding || this.played || index < 0 || index >= this.length || this.viewed && index === previousIndex) {
2086
2163
  return this;
2087
2164
  }
2165
+ var originalEvent = this.actionEvent || this.viewOriginalEvent || null;
2166
+ this.actionEvent = null;
2167
+ this.viewOriginalEvent = originalEvent;
2088
2168
  if (!this.isShown) {
2089
2169
  this.index = index;
2090
2170
  return this.show();
@@ -2116,7 +2196,8 @@ var methods = {
2116
2196
  if (dispatchEvent(element, EVENT_VIEW, {
2117
2197
  originalImage: this.images[index],
2118
2198
  index: index,
2119
- image: image
2199
+ image: image,
2200
+ originalEvent: originalEvent
2120
2201
  }) === false || !this.isShown || this.hiding || this.played) {
2121
2202
  return this;
2122
2203
  }
@@ -2173,62 +2254,75 @@ var methods = {
2173
2254
  }
2174
2255
  }
2175
2256
  };
2176
- var onLoad;
2177
- var onError;
2178
2257
  addListener(element, EVENT_VIEWED, onViewed, {
2179
2258
  once: true
2180
2259
  });
2181
- this.viewing = {
2182
- abort: function abort() {
2183
- removeListener(element, EVENT_VIEWED, onViewed);
2184
- if (image.complete) {
2185
- if (_this2.imageRendering) {
2186
- _this2.imageRendering.abort();
2187
- } else if (_this2.imageInitializing) {
2188
- _this2.imageInitializing.abort();
2189
- }
2190
- } else {
2191
- // Cancel download to save bandwidth.
2192
- image.src = '';
2193
- removeListener(image, EVENT_LOAD, onLoad);
2194
- if (_this2.timeout) {
2195
- clearTimeout(_this2.timeout);
2196
- }
2197
- }
2198
- }
2199
- };
2200
- if (image.complete) {
2201
- this.load();
2202
- } else {
2203
- addListener(image, EVENT_LOAD, onLoad = function onLoad() {
2204
- removeListener(image, EVENT_ERROR, onError);
2205
- _this2.load();
2206
- }, {
2207
- once: true
2208
- });
2209
- addListener(image, EVENT_ERROR, onError = function onError() {
2260
+ var _loadImage = function loadImage() {
2261
+ var isFallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
2262
+ var onLoad;
2263
+ var onError;
2264
+ var clean = function clean() {
2210
2265
  removeListener(image, EVENT_LOAD, onLoad);
2266
+ removeListener(image, EVENT_ERROR, onError);
2211
2267
  if (_this2.timeout) {
2212
2268
  clearTimeout(_this2.timeout);
2213
2269
  _this2.timeout = false;
2214
2270
  }
2215
- removeClass(image, CLASS_INVISIBLE);
2216
- if (options.loading) {
2217
- removeClass(_this2.canvas, CLASS_LOADING);
2271
+ };
2272
+ _this2.viewing = {
2273
+ abort: function abort() {
2274
+ removeListener(element, EVENT_VIEWED, onViewed);
2275
+ if (image.complete) {
2276
+ if (_this2.imageRendering) {
2277
+ _this2.imageRendering.abort();
2278
+ } else if (_this2.imageInitializing) {
2279
+ _this2.imageInitializing.abort();
2280
+ }
2281
+ } else {
2282
+ // Cancel download to save bandwidth.
2283
+ image.src = '';
2284
+ clean();
2285
+ }
2286
+ }
2287
+ };
2288
+ if (image.complete) {
2289
+ _this2.load();
2290
+ } else {
2291
+ addListener(image, EVENT_LOAD, onLoad = function onLoad() {
2292
+ clean();
2293
+ _this2.load();
2294
+ }, {
2295
+ once: true
2296
+ });
2297
+ addListener(image, EVENT_ERROR, onError = function onError() {
2298
+ clean();
2299
+ if (!isFallback) {
2300
+ var fallbackSrc = img.src;
2301
+ if (fallbackSrc && fallbackSrc !== image.src) {
2302
+ image.src = fallbackSrc;
2303
+ _loadImage(true);
2304
+ return;
2305
+ }
2306
+ }
2307
+ removeClass(image, CLASS_INVISIBLE);
2308
+ if (options.loading) {
2309
+ removeClass(_this2.canvas, CLASS_LOADING);
2310
+ }
2311
+ }, {
2312
+ once: true
2313
+ });
2314
+ if (_this2.timeout) {
2315
+ clearTimeout(_this2.timeout);
2218
2316
  }
2219
- }, {
2220
- once: true
2221
- });
2222
- if (this.timeout) {
2223
- clearTimeout(this.timeout);
2224
- }
2225
2317
 
2226
- // Make the image visible if it fails to load within 1s
2227
- this.timeout = setTimeout(function () {
2228
- removeClass(image, CLASS_INVISIBLE);
2229
- _this2.timeout = false;
2230
- }, 1000);
2231
- }
2318
+ // Make the image visible if it fails to load within 1s
2319
+ _this2.timeout = setTimeout(function () {
2320
+ removeClass(image, CLASS_INVISIBLE);
2321
+ _this2.timeout = false;
2322
+ }, 1000);
2323
+ }
2324
+ };
2325
+ _loadImage();
2232
2326
  return this;
2233
2327
  },
2234
2328
  /**
@@ -2278,13 +2372,11 @@ var methods = {
2278
2372
  * Move the image to an absolute point.
2279
2373
  * @param {number} x - The new position in the horizontal direction.
2280
2374
  * @param {number} [y=x] - The new position in the vertical direction.
2281
- * @param {Event} [_originalEvent=null] - The original event if any.
2282
2375
  * @returns {Viewer} this
2283
2376
  */
2284
2377
  moveTo: function moveTo(x) {
2285
2378
  var _this3 = this;
2286
2379
  var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
2287
- var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2288
2380
  var element = this.element,
2289
2381
  options = this.options,
2290
2382
  imageData = this.imageData;
@@ -2305,6 +2397,8 @@ var methods = {
2305
2397
  y = oldY;
2306
2398
  }
2307
2399
  if (changed) {
2400
+ var originalEvent = this.actionEvent || null;
2401
+ this.actionEvent = null;
2308
2402
  if (isFunction(options.move)) {
2309
2403
  addListener(element, EVENT_MOVE, options.move, {
2310
2404
  once: true
@@ -2315,7 +2409,7 @@ var methods = {
2315
2409
  y: y,
2316
2410
  oldX: oldX,
2317
2411
  oldY: oldY,
2318
- originalEvent: _originalEvent
2412
+ originalEvent: originalEvent
2319
2413
  }) === false) {
2320
2414
  return this;
2321
2415
  }
@@ -2337,7 +2431,7 @@ var methods = {
2337
2431
  y: y,
2338
2432
  oldX: oldX,
2339
2433
  oldY: oldY,
2340
- originalEvent: _originalEvent
2434
+ originalEvent: originalEvent
2341
2435
  }, {
2342
2436
  cancelable: false
2343
2437
  });
@@ -2368,6 +2462,8 @@ var methods = {
2368
2462
  degree = Number(degree);
2369
2463
  if (isNumber(degree) && this.viewed && !this.played && options.rotatable) {
2370
2464
  var oldDegree = imageData.rotate;
2465
+ var originalEvent = this.actionEvent || null;
2466
+ this.actionEvent = null;
2371
2467
  if (isFunction(options.rotate)) {
2372
2468
  addListener(element, EVENT_ROTATE, options.rotate, {
2373
2469
  once: true
@@ -2375,7 +2471,8 @@ var methods = {
2375
2471
  }
2376
2472
  if (dispatchEvent(element, EVENT_ROTATE, {
2377
2473
  degree: degree,
2378
- oldDegree: oldDegree
2474
+ oldDegree: oldDegree,
2475
+ originalEvent: originalEvent
2379
2476
  }) === false) {
2380
2477
  return this;
2381
2478
  }
@@ -2391,7 +2488,8 @@ var methods = {
2391
2488
  }
2392
2489
  dispatchEvent(element, EVENT_ROTATED, {
2393
2490
  degree: degree,
2394
- oldDegree: oldDegree
2491
+ oldDegree: oldDegree,
2492
+ originalEvent: originalEvent
2395
2493
  }, {
2396
2494
  cancelable: false
2397
2495
  });
@@ -2446,6 +2544,8 @@ var methods = {
2446
2544
  scaleY = oldScaleY;
2447
2545
  }
2448
2546
  if (changed) {
2547
+ var originalEvent = this.actionEvent || null;
2548
+ this.actionEvent = null;
2449
2549
  if (isFunction(options.scale)) {
2450
2550
  addListener(element, EVENT_SCALE, options.scale, {
2451
2551
  once: true
@@ -2455,7 +2555,8 @@ var methods = {
2455
2555
  scaleX: scaleX,
2456
2556
  scaleY: scaleY,
2457
2557
  oldScaleX: oldScaleX,
2458
- oldScaleY: oldScaleY
2558
+ oldScaleY: oldScaleY,
2559
+ originalEvent: originalEvent
2459
2560
  }) === false) {
2460
2561
  return this;
2461
2562
  }
@@ -2474,7 +2575,8 @@ var methods = {
2474
2575
  scaleX: scaleX,
2475
2576
  scaleY: scaleY,
2476
2577
  oldScaleX: oldScaleX,
2477
- oldScaleY: oldScaleY
2578
+ oldScaleY: oldScaleY,
2579
+ originalEvent: originalEvent
2478
2580
  }, {
2479
2581
  cancelable: false
2480
2582
  });
@@ -2488,13 +2590,11 @@ var methods = {
2488
2590
  * @param {number} ratio - The target ratio.
2489
2591
  * @param {boolean} [showTooltip=false] - Indicates whether to show the tooltip.
2490
2592
  * @param {Object} [pivot] - The pivot point coordinate for zooming.
2491
- * @param {Event} [_originalEvent=null] - The original event if any.
2492
2593
  * @returns {Viewer} this
2493
2594
  */
2494
2595
  zoom: function zoom(ratio) {
2495
2596
  var showTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2496
2597
  var pivot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2497
- var _originalEvent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
2498
2598
  var imageData = this.imageData;
2499
2599
  ratio = Number(ratio);
2500
2600
  if (ratio < 0) {
@@ -2502,7 +2602,7 @@ var methods = {
2502
2602
  } else {
2503
2603
  ratio = 1 + ratio;
2504
2604
  }
2505
- this.zoomTo(imageData.width * ratio / imageData.naturalWidth, showTooltip, pivot, _originalEvent);
2605
+ this.zoomTo(imageData.width * ratio / imageData.naturalWidth, showTooltip, pivot);
2506
2606
  return this;
2507
2607
  },
2508
2608
  /**
@@ -2510,16 +2610,14 @@ var methods = {
2510
2610
  * @param {number} ratio - The target ratio.
2511
2611
  * @param {boolean} [showTooltip] - Indicates whether to show the tooltip.
2512
2612
  * @param {Object} [pivot] - The pivot point coordinate for zooming.
2513
- * @param {Event} [_originalEvent=null] - The original event if any.
2514
- * @param {Event} [_zoomable=false] - Indicates if the current zoom is available or not.
2613
+ * @param {boolean} [_zoomable=false] - Indicates if the current zoom is available or not.
2515
2614
  * @returns {Viewer} this
2516
2615
  */
2517
2616
  zoomTo: function zoomTo(ratio) {
2518
2617
  var _this6 = this;
2519
2618
  var showTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2520
2619
  var pivot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2521
- var _originalEvent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
2522
- var _zoomable = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
2620
+ var _zoomable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
2523
2621
  var element = this.element,
2524
2622
  options = this.options,
2525
2623
  pointers = this.pointers,
@@ -2537,8 +2635,10 @@ var methods = {
2537
2635
  var maxZoomRatio = Math.min(100, isFunction(options.maxZoomRatio) ? options.maxZoomRatio.call(this, this.image, imageData) : options.maxZoomRatio);
2538
2636
  ratio = Math.min(Math.max(ratio, minZoomRatio), maxZoomRatio);
2539
2637
  }
2540
- if (_originalEvent) {
2541
- switch (_originalEvent.type) {
2638
+ var originalEvent = this.actionEvent || null;
2639
+ this.actionEvent = null;
2640
+ if (originalEvent && originalEvent.type !== EVENT_CLICK) {
2641
+ switch (originalEvent.type) {
2542
2642
  case 'wheel':
2543
2643
  if (options.zoomRatio >= 0.055 && ratio > 0.95 && ratio < 1.05) {
2544
2644
  ratio = 1;
@@ -2566,16 +2666,16 @@ var methods = {
2566
2666
  if (dispatchEvent(element, EVENT_ZOOM, {
2567
2667
  ratio: ratio,
2568
2668
  oldRatio: oldRatio,
2569
- originalEvent: _originalEvent
2669
+ originalEvent: originalEvent
2570
2670
  }) === false) {
2571
2671
  return this;
2572
2672
  }
2573
2673
  this.zooming = true;
2574
- if (_originalEvent) {
2674
+ if (originalEvent && originalEvent.type !== EVENT_CLICK) {
2575
2675
  var offset = getOffset(this.viewer);
2576
2676
  var center = pointers && Object.keys(pointers).length > 0 ? getPointersCenter(pointers) : {
2577
- pageX: _originalEvent.pageX,
2578
- pageY: _originalEvent.pageY
2677
+ pageX: originalEvent.pageX,
2678
+ pageY: originalEvent.pageY
2579
2679
  };
2580
2680
 
2581
2681
  // Zoom from the triggering point of the event
@@ -2606,7 +2706,7 @@ var methods = {
2606
2706
  dispatchEvent(element, EVENT_ZOOMED, {
2607
2707
  ratio: ratio,
2608
2708
  oldRatio: oldRatio,
2609
- originalEvent: _originalEvent
2709
+ originalEvent: originalEvent
2610
2710
  }, {
2611
2711
  cancelable: false
2612
2712
  });
@@ -2630,12 +2730,16 @@ var methods = {
2630
2730
  }
2631
2731
  var element = this.element,
2632
2732
  options = this.options;
2733
+ var originalEvent = this.actionEvent || null;
2734
+ this.actionEvent = null;
2633
2735
  if (isFunction(options.play)) {
2634
2736
  addListener(element, EVENT_PLAY, options.play, {
2635
2737
  once: true
2636
2738
  });
2637
2739
  }
2638
- if (dispatchEvent(element, EVENT_PLAY) === false) {
2740
+ if (dispatchEvent(element, EVENT_PLAY, {
2741
+ originalEvent: originalEvent
2742
+ }) === false) {
2639
2743
  return this;
2640
2744
  }
2641
2745
  var player = this.player;
@@ -2649,6 +2753,7 @@ var methods = {
2649
2753
  this.requestFullscreen(fullscreen);
2650
2754
  }
2651
2755
  addClass(player, CLASS_SHOW);
2756
+ player.removeAttribute('aria-hidden');
2652
2757
  forEach(this.images, function (originalImage, i) {
2653
2758
  var image = document.createElement('img');
2654
2759
  image.src = _this7.getImageURL(originalImage) || originalImage.src;
@@ -2670,17 +2775,51 @@ var methods = {
2670
2775
  if (isNumber(options.interval) && options.interval > 0) {
2671
2776
  var _prev = function prev() {
2672
2777
  clearTimeout(_this7.playing.timeout);
2778
+ var currentOriginalEvent = _this7.actionEvent || null;
2779
+ _this7.actionEvent = null;
2780
+ var prevIndex = index - 1;
2781
+ prevIndex = prevIndex >= 0 ? prevIndex : total - 1;
2782
+ if (isFunction(options.playing)) {
2783
+ addListener(element, EVENT_PLAYING, options.playing, {
2784
+ once: true
2785
+ });
2786
+ }
2787
+ if (dispatchEvent(element, EVENT_PLAYING, {
2788
+ originalImage: _this7.images[prevIndex],
2789
+ index: prevIndex,
2790
+ image: list[prevIndex],
2791
+ originalEvent: currentOriginalEvent
2792
+ }) === false) {
2793
+ _this7.playing.timeout = options.autoplay ? setTimeout(_prev, options.interval) : null;
2794
+ return;
2795
+ }
2673
2796
  removeClass(list[index], CLASS_IN);
2674
- index -= 1;
2675
- index = index >= 0 ? index : total - 1;
2797
+ index = prevIndex;
2676
2798
  addClass(list[index], CLASS_IN);
2677
2799
  _this7.playing.timeout = options.autoplay ? setTimeout(_prev, options.interval) : null;
2678
2800
  };
2679
2801
  var _next = function next() {
2680
2802
  clearTimeout(_this7.playing.timeout);
2803
+ var currentOriginalEvent = _this7.actionEvent || null;
2804
+ _this7.actionEvent = null;
2805
+ var nextIndex = index + 1;
2806
+ nextIndex = nextIndex < total ? nextIndex : 0;
2807
+ if (isFunction(options.playing)) {
2808
+ addListener(element, EVENT_PLAYING, options.playing, {
2809
+ once: true
2810
+ });
2811
+ }
2812
+ if (dispatchEvent(element, EVENT_PLAYING, {
2813
+ originalImage: _this7.images[nextIndex],
2814
+ index: nextIndex,
2815
+ image: list[nextIndex],
2816
+ originalEvent: currentOriginalEvent
2817
+ }) === false) {
2818
+ _this7.playing.timeout = options.autoplay ? setTimeout(_next, options.interval) : null;
2819
+ return;
2820
+ }
2681
2821
  removeClass(list[index], CLASS_IN);
2682
- index += 1;
2683
- index = index < total ? index : 0;
2822
+ index = nextIndex;
2684
2823
  addClass(list[index], CLASS_IN);
2685
2824
  _this7.playing.timeout = options.autoplay ? setTimeout(_next, options.interval) : null;
2686
2825
  };
@@ -2694,7 +2833,10 @@ var methods = {
2694
2833
  }
2695
2834
  return this;
2696
2835
  },
2697
- // Stop play
2836
+ /**
2837
+ * Stop play
2838
+ * @returns {Viewer} this
2839
+ */
2698
2840
  stop: function stop() {
2699
2841
  var _this8 = this;
2700
2842
  if (!this.played) {
@@ -2702,12 +2844,16 @@ var methods = {
2702
2844
  }
2703
2845
  var element = this.element,
2704
2846
  options = this.options;
2847
+ var originalEvent = this.actionEvent || null;
2848
+ this.actionEvent = null;
2705
2849
  if (isFunction(options.stop)) {
2706
2850
  addListener(element, EVENT_STOP, options.stop, {
2707
2851
  once: true
2708
2852
  });
2709
2853
  }
2710
- if (dispatchEvent(element, EVENT_STOP) === false) {
2854
+ if (dispatchEvent(element, EVENT_STOP, {
2855
+ originalEvent: originalEvent
2856
+ }) === false) {
2711
2857
  return this;
2712
2858
  }
2713
2859
  var player = this.player;
@@ -2718,6 +2864,7 @@ var methods = {
2718
2864
  removeListener(image, EVENT_LOAD, _this8.onLoadWhenPlay);
2719
2865
  });
2720
2866
  removeClass(player, CLASS_SHOW);
2867
+ player.setAttribute('aria-hidden', true);
2721
2868
  player.innerHTML = '';
2722
2869
  this.exitFullscreen();
2723
2870
  return this;
@@ -2850,15 +2997,13 @@ var methods = {
2850
2997
  },
2851
2998
  /**
2852
2999
  * Toggle the image size between its current size and natural size
2853
- * @param {Event} [_originalEvent=null] - The original event if any.
2854
3000
  * @returns {Viewer} this
2855
3001
  */
2856
3002
  toggle: function toggle() {
2857
- var _originalEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
2858
3003
  if (this.imageData.ratio === 1) {
2859
- this.zoomTo(this.imageData.oldRatio, true, null, _originalEvent);
3004
+ this.zoomTo(this.imageData.oldRatio, true);
2860
3005
  } else {
2861
- this.zoomTo(1, true, null, _originalEvent);
3006
+ this.zoomTo(1, true);
2862
3007
  }
2863
3008
  return this;
2864
3009
  },
@@ -3073,9 +3218,12 @@ var others = {
3073
3218
  once: true
3074
3219
  });
3075
3220
  }
3076
- if (dispatchEvent(element, EVENT_SHOWN) === false) {
3221
+ if (dispatchEvent(element, EVENT_SHOWN, {
3222
+ originalEvent: this.showOriginalEvent || null
3223
+ }) === false) {
3077
3224
  return;
3078
3225
  }
3226
+ this.showOriginalEvent = null;
3079
3227
  if (this.ready && this.isShown && !this.hiding) {
3080
3228
  this.view(this.index);
3081
3229
  }
@@ -3112,9 +3260,12 @@ var others = {
3112
3260
  once: true
3113
3261
  });
3114
3262
  }
3115
- dispatchEvent(element, EVENT_HIDDEN, null, {
3263
+ dispatchEvent(element, EVENT_HIDDEN, {
3264
+ originalEvent: this.hideOriginalEvent || null
3265
+ }, {
3116
3266
  cancelable: false
3117
3267
  });
3268
+ this.hideOriginalEvent = null;
3118
3269
  }
3119
3270
  },
3120
3271
  requestFullscreen: function requestFullscreen(options) {
@@ -3170,7 +3321,8 @@ var others = {
3170
3321
  case ACTION_MOVE:
3171
3322
  if (offsetX !== 0 || offsetY !== 0) {
3172
3323
  this.pointerMoved = true;
3173
- this.move(offsetX, offsetY, event);
3324
+ this.actionEvent = event;
3325
+ this.move(offsetX, offsetY);
3174
3326
  }
3175
3327
  break;
3176
3328
 
@@ -3179,7 +3331,8 @@ var others = {
3179
3331
  if (options.zoomable && options.zoomOnTouch) {
3180
3332
  var zoomRatio = getMaxZoomRatio(pointers);
3181
3333
  if (zoomRatio !== 0) {
3182
- this.zoom(zoomRatio, false, null, event);
3334
+ this.actionEvent = event;
3335
+ this.zoom(zoomRatio);
3183
3336
  }
3184
3337
  }
3185
3338
  break;
@@ -3189,7 +3342,8 @@ var others = {
3189
3342
  if (options.rotatable && options.rotateOnTouch) {
3190
3343
  var rotateDegree = getMaxRotateDegree(pointers);
3191
3344
  if (rotateDegree !== 0) {
3192
- this.rotate(rotateDegree, event);
3345
+ this.actionEvent = event;
3346
+ this.rotate(rotateDegree);
3193
3347
  }
3194
3348
  }
3195
3349
  break;
@@ -3199,13 +3353,15 @@ var others = {
3199
3353
  if (options.zoomable && options.zoomOnTouch) {
3200
3354
  var _zoomRatio = getMaxZoomRatio(pointers);
3201
3355
  if (_zoomRatio !== 0) {
3202
- this.zoom(_zoomRatio, false, null, event);
3356
+ this.actionEvent = event;
3357
+ this.zoom(_zoomRatio);
3203
3358
  }
3204
3359
  }
3205
3360
  if (options.rotatable && options.rotateOnTouch) {
3206
3361
  var _rotateDegree = getMaxRotateDegree(pointers);
3207
3362
  if (_rotateDegree !== 0) {
3208
- this.rotate(_rotateDegree, event);
3363
+ this.actionEvent = event;
3364
+ this.rotate(_rotateDegree);
3209
3365
  }
3210
3366
  }
3211
3367
  break;
@@ -3216,6 +3372,7 @@ var others = {
3216
3372
  if (absoluteOffsetX > 1 && absoluteOffsetX > Math.abs(offsetY)) {
3217
3373
  // Empty `pointers` as `touchend` event will not be fired after swiped in iOS browsers.
3218
3374
  this.pointers = {};
3375
+ this.actionEvent = event;
3219
3376
  if (offsetX > 1) {
3220
3377
  this.prev(options.loop);
3221
3378
  } else if (offsetX < -1) {
@@ -3262,6 +3419,7 @@ var Viewer = /*#__PURE__*/function () {
3262
3419
  this.ownerDocument = element.ownerDocument || element.host.ownerDocument;
3263
3420
  this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
3264
3421
  this.action = false;
3422
+ this.actionEvent = null;
3265
3423
  this.fading = false;
3266
3424
  this.fulled = false;
3267
3425
  this.hiding = false;
@@ -3375,9 +3533,10 @@ var Viewer = /*#__PURE__*/function () {
3375
3533
  }
3376
3534
  });
3377
3535
  } else {
3378
- addListener(element, EVENT_CLICK, this.onElementClick = function (_ref) {
3379
- var target = _ref.target;
3536
+ addListener(element, EVENT_CLICK, this.onElementClick = function (event) {
3537
+ var target = event.target;
3380
3538
  if (target.localName === 'img' && (!isFunction(options.filter) || options.filter.call(_this, target))) {
3539
+ _this.actionEvent = event;
3381
3540
  _this.view(_this.images.indexOf(target));
3382
3541
  }
3383
3542
  });
@@ -3387,6 +3546,7 @@ var Viewer = /*#__PURE__*/function () {
3387
3546
  if (target.localName === 'img' && (key === 'Enter' || key === ' ')) {
3388
3547
  event.preventDefault();
3389
3548
  if (!isFunction(options.filter) || options.filter.call(_this, target)) {
3549
+ _this.actionEvent = event;
3390
3550
  _this.view(_this.images.indexOf(target));
3391
3551
  }
3392
3552
  }
@@ -3428,6 +3588,9 @@ var Viewer = /*#__PURE__*/function () {
3428
3588
  viewer.id = "".concat(NAMESPACE).concat(this.id);
3429
3589
  title.id = "".concat(NAMESPACE, "Title").concat(this.id);
3430
3590
  addClass(title, !options.title ? CLASS_HIDE : getResponsiveClass(Array.isArray(options.title) ? options.title[0] : options.title));
3591
+ if (options.title) {
3592
+ title.removeAttribute('aria-hidden');
3593
+ }
3431
3594
  var navbarOptions = isPlainObject(options.navbar) ? options.navbar : {};
3432
3595
  var navbarShow = options.navbar;
3433
3596
  var navbarSize = !isUndefined(navbarOptions.size) ? navbarOptions.size : options.navbar;
@@ -3435,6 +3598,9 @@ var Viewer = /*#__PURE__*/function () {
3435
3598
  navbarShow = !isUndefined(navbarOptions.show) ? navbarOptions.show : true;
3436
3599
  }
3437
3600
  addClass(navbar, !navbarShow ? CLASS_HIDE : getResponsiveClass(navbarShow));
3601
+ if (navbarShow) {
3602
+ navbar.removeAttribute('aria-hidden');
3603
+ }
3438
3604
  if (['small', 'medium', 'large'].indexOf(navbarSize) !== -1) {
3439
3605
  addClass(navbar, "".concat(NAMESPACE, "-").concat(navbarSize));
3440
3606
  }
@@ -3456,7 +3622,13 @@ var Viewer = /*#__PURE__*/function () {
3456
3622
  } else {
3457
3623
  addClass(navigation, !options.navigation ? CLASS_HIDE : getResponsiveClass(options.navigation));
3458
3624
  }
3625
+ if (options.navigation) {
3626
+ navigation.removeAttribute('aria-hidden');
3627
+ }
3459
3628
  toggleClass(button, CLASS_HIDE, !options.button);
3629
+ if (options.button) {
3630
+ button.removeAttribute('aria-hidden');
3631
+ }
3460
3632
  if (options.keyboard) {
3461
3633
  button.setAttribute('tabindex', 0);
3462
3634
  forEach(navigation.querySelectorAll('[role="button"]'), function (item) {
@@ -3484,6 +3656,7 @@ var Viewer = /*#__PURE__*/function () {
3484
3656
  if (!custom) {
3485
3657
  addClass(toolbar, getResponsiveClass(options.toolbar));
3486
3658
  }
3659
+ toolbar.removeAttribute('aria-hidden');
3487
3660
  forEach(custom ? options.toolbar : BUTTONS, function (value, index) {
3488
3661
  var deep = custom && isPlainObject(value);
3489
3662
  var name = custom ? hyphenate(index) : value;
@@ -3519,6 +3692,11 @@ var Viewer = /*#__PURE__*/function () {
3519
3692
  } else {
3520
3693
  addClass(toolbar, CLASS_HIDE);
3521
3694
  }
3695
+ if (options.title || navbarShow || options.toolbar) {
3696
+ this.footer.removeAttribute('aria-hidden');
3697
+ } else {
3698
+ addClass(this.footer, CLASS_HIDE);
3699
+ }
3522
3700
  if (!options.rotatable) {
3523
3701
  var rotates = toolbar.querySelectorAll('li[class*="rotate"]');
3524
3702
  addClass(rotates, CLASS_INVISIBLE);