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
  function _classCallCheck(a, n) {
@@ -240,7 +240,10 @@ var DEFAULTS = {
240
240
  zoomOnGesture: true,
241
241
  /**
242
242
  * Enable to zoom the image by wheeling mouse.
243
- * @type {boolean}
243
+ * Set to a modifier key name (`ctrl`, `shift`, `alt`, `meta`), or a
244
+ * combination joined with `+` (e.g. `ctrl+shift`), to only zoom when
245
+ * the given modifier key(s) are held down while wheeling.
246
+ * @type {boolean | string}
244
247
  */
245
248
  zoomOnWheel: true,
246
249
  /**
@@ -248,6 +251,16 @@ var DEFAULTS = {
248
251
  * @type {boolean}
249
252
  */
250
253
  slideOnTouch: true,
254
+ /**
255
+ * Enable to slide to the next or previous image by wheeling mouse.
256
+ * Set to a modifier key name (`ctrl`, `shift`, `alt`, `meta`), or a
257
+ * combination joined with `+` (e.g. `ctrl+shift`), to only slide when
258
+ * the given modifier key(s) are held down while wheeling.
259
+ * Takes effect over the navbar, and also over the rest of the viewer
260
+ * when `zoomOnWheel` doesn't take effect for the wheel event.
261
+ * @type {boolean | string}
262
+ */
263
+ slideOnWheel: true,
251
264
  /**
252
265
  * Indicate if toggle the image size between its natural size
253
266
  * and initial size when double click on the image or not.
@@ -314,10 +327,11 @@ var DEFAULTS = {
314
327
  zoom: null,
315
328
  zoomed: null,
316
329
  play: null,
330
+ playing: null,
317
331
  stop: null
318
332
  };
319
333
 
320
- 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>';
334
+ 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>';
321
335
 
322
336
  var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
323
337
  var WINDOW = IS_BROWSER ? window : {};
@@ -389,6 +403,7 @@ var EVENT_SCALED = 'scaled';
389
403
  var EVENT_ZOOM = 'zoom';
390
404
  var EVENT_ZOOMED = 'zoomed';
391
405
  var EVENT_PLAY = 'play';
406
+ var EVENT_PLAYING = 'playing';
392
407
  var EVENT_STOP = 'stop';
393
408
 
394
409
  // Data keys
@@ -408,6 +423,30 @@ var BUTTONS = ['zoom-in', 'zoom-out', 'one-to-one', 'reset', 'prev', 'play', 'ne
408
423
  function isString(value) {
409
424
  return typeof value === 'string';
410
425
  }
426
+ var MODIFIER_KEY_PROPERTIES = {
427
+ ctrl: 'ctrlKey',
428
+ shift: 'shiftKey',
429
+ alt: 'altKey',
430
+ meta: 'metaKey'
431
+ };
432
+
433
+ /**
434
+ * Check if a wheel option (`zoomOnWheel` or `slideOnWheel`) takes effect for the given wheel event.
435
+ * @param {boolean | string} option - The option value.
436
+ * @param {WheelEvent} event - The wheel event.
437
+ * @returns {boolean} Returns `true` if the option takes effect for the event, else `false`.
438
+ */
439
+ function isWheelActionEnabled(option, event) {
440
+ if (!option) {
441
+ return false;
442
+ }
443
+ if (option === true) {
444
+ return true;
445
+ }
446
+ return isString(option) && option.split('+').every(function (key) {
447
+ return event[MODIFIER_KEY_PROPERTIES[key.trim().toLowerCase()]];
448
+ });
449
+ }
411
450
 
412
451
  /**
413
452
  * Check if the given value is not a number.
@@ -1076,6 +1115,9 @@ var render = {
1076
1115
  var items = [];
1077
1116
  var navbarOptions = isPlainObject(options.navbar) ? options.navbar : {};
1078
1117
  var probe = document.createElement('li');
1118
+ if (!this.containerData) {
1119
+ this.initContainer();
1120
+ }
1079
1121
  list.appendChild(probe);
1080
1122
  var itemWidth = probe.offsetWidth + parseInt(window.getComputedStyle(probe).marginLeft, 10);
1081
1123
  list.removeChild(probe);
@@ -1330,7 +1372,7 @@ var events = {
1330
1372
  addListener(document, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));
1331
1373
  addListener(document, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));
1332
1374
  addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
1333
- if (options.zoomable && options.zoomOnWheel) {
1375
+ if (options.zoomable && options.zoomOnWheel || options.slideOnWheel) {
1334
1376
  addListener(viewer, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
1335
1377
  passive: false,
1336
1378
  capture: true
@@ -1360,7 +1402,7 @@ var events = {
1360
1402
  removeListener(document, EVENT_POINTER_UP, this.onPointerUp);
1361
1403
  removeListener(document, EVENT_KEY_DOWN, this.onKeyDown);
1362
1404
  removeListener(window, EVENT_RESIZE, this.onResize);
1363
- if (options.zoomable && options.zoomOnWheel) {
1405
+ if (options.zoomable && options.zoomOnWheel || options.slideOnWheel) {
1364
1406
  removeListener(viewer, EVENT_WHEEL, this.onWheel, {
1365
1407
  passive: false,
1366
1408
  capture: true
@@ -1392,6 +1434,7 @@ var handlers = {
1392
1434
  if (IS_TOUCH_DEVICE && event.isTrusted && target === this.canvas) {
1393
1435
  clearTimeout(this.clickCanvasTimeout);
1394
1436
  }
1437
+ this.actionEvent = event;
1395
1438
  switch (action) {
1396
1439
  case 'mix':
1397
1440
  if (this.played) {
@@ -1462,7 +1505,8 @@ var handlers = {
1462
1505
  }
1463
1506
 
1464
1507
  // XXX: No pageX/Y properties in custom event, fallback to the original event.
1465
- this.toggle(event.isTrusted ? event : event.detail && event.detail.originalEvent);
1508
+ this.actionEvent = event.isTrusted ? event : event.detail && event.detail.originalEvent;
1509
+ this.toggle();
1466
1510
  }
1467
1511
  },
1468
1512
  load: function load() {
@@ -1498,10 +1542,12 @@ var handlers = {
1498
1542
  dispatchEvent(element, EVENT_VIEWED, {
1499
1543
  originalImage: _this.images[index],
1500
1544
  index: index,
1501
- image: image
1545
+ image: image,
1546
+ originalEvent: _this.viewOriginalEvent || null
1502
1547
  }, {
1503
1548
  cancelable: false
1504
1549
  });
1550
+ _this.viewOriginalEvent = null;
1505
1551
  });
1506
1552
  });
1507
1553
  },
@@ -1541,6 +1587,7 @@ var handlers = {
1541
1587
  return;
1542
1588
  }
1543
1589
  var keyCode = event.keyCode || event.which || event.charCode;
1590
+ this.actionEvent = event;
1544
1591
  switch (keyCode) {
1545
1592
  // Enter
1546
1593
  case 13:
@@ -1866,6 +1913,8 @@ var handlers = {
1866
1913
  },
1867
1914
  wheel: function wheel(event) {
1868
1915
  var _this4 = this;
1916
+ var options = this.options,
1917
+ navbar = this.navbar;
1869
1918
  if (!this.viewed) {
1870
1919
  return;
1871
1920
  }
@@ -1874,7 +1923,7 @@ var handlers = {
1874
1923
  return;
1875
1924
  }
1876
1925
 
1877
- // Limit wheel speed to prevent zoom too fast
1926
+ // Limit wheel speed to prevent zoom or slide too fast
1878
1927
  if (this.wheeling) {
1879
1928
  return;
1880
1929
  }
@@ -1882,7 +1931,6 @@ var handlers = {
1882
1931
  setTimeout(function () {
1883
1932
  _this4.wheeling = false;
1884
1933
  }, 50);
1885
- var ratio = Number(this.options.zoomRatio) || 0.1;
1886
1934
  var delta = 1;
1887
1935
  if (event.deltaY) {
1888
1936
  delta = event.deltaY > 0 ? 1 : -1;
@@ -1891,7 +1939,24 @@ var handlers = {
1891
1939
  } else if (event.detail) {
1892
1940
  delta = event.detail > 0 ? 1 : -1;
1893
1941
  }
1894
- this.zoom(-delta * ratio, true, null, event);
1942
+
1943
+ // Wheeling over the navbar never zooms, only slides
1944
+ var overNavbar = navbar && navbar.contains(event.target);
1945
+ var zoomable = !overNavbar && options.zoomable && isWheelActionEnabled(options.zoomOnWheel, event);
1946
+ if (zoomable) {
1947
+ var ratio = Number(options.zoomRatio) || 0.1;
1948
+ this.actionEvent = event;
1949
+ this.zoom(-delta * ratio, true);
1950
+ return;
1951
+ }
1952
+ if (isWheelActionEnabled(options.slideOnWheel, event)) {
1953
+ this.actionEvent = event;
1954
+ if (delta > 0) {
1955
+ this.next(options.loop);
1956
+ } else if (delta < 0) {
1957
+ this.prev(options.loop);
1958
+ }
1959
+ }
1895
1960
  },
1896
1961
  gesture: function gesture(event) {
1897
1962
  var options = this.options;
@@ -1913,11 +1978,13 @@ var handlers = {
1913
1978
  var degree = rotation - (this.gestureRotation || 0);
1914
1979
  this.gestureScale = scale;
1915
1980
  if (options.zoomable && options.zoomOnGesture && ratio !== 1) {
1916
- this.zoom(ratio >= 1 ? ratio - 1 : 1 - 1 / ratio, false, null, event);
1981
+ this.actionEvent = event;
1982
+ this.zoom(ratio >= 1 ? ratio - 1 : 1 - 1 / ratio);
1917
1983
  }
1918
1984
  if (options.rotatable && options.rotateOnGesture && isNumber(rotation)) {
1919
1985
  this.gestureRotation = rotation;
1920
1986
  if (degree !== 0) {
1987
+ this.actionEvent = event;
1921
1988
  this.rotate(degree);
1922
1989
  }
1923
1990
  }
@@ -1951,12 +2018,17 @@ var methods = {
1951
2018
  }
1952
2019
  return this;
1953
2020
  }
2021
+ var originalEvent = this.actionEvent || this.showOriginalEvent || this.viewOriginalEvent || null;
2022
+ this.actionEvent = null;
2023
+ this.showOriginalEvent = originalEvent;
1954
2024
  if (isFunction(options.show)) {
1955
2025
  addListener(element, EVENT_SHOW, options.show, {
1956
2026
  once: true
1957
2027
  });
1958
2028
  }
1959
- if (dispatchEvent(element, EVENT_SHOW) === false || !this.ready) {
2029
+ if (dispatchEvent(element, EVENT_SHOW, {
2030
+ originalEvent: originalEvent
2031
+ }) === false || !this.ready) {
1960
2032
  return this;
1961
2033
  }
1962
2034
  if (this.hiding) {
@@ -2005,12 +2077,17 @@ var methods = {
2005
2077
  if (options.inline || this.hiding || !(this.isShown || this.showing)) {
2006
2078
  return this;
2007
2079
  }
2080
+ var originalEvent = this.actionEvent || this.hideOriginalEvent || null;
2081
+ this.actionEvent = null;
2082
+ this.hideOriginalEvent = originalEvent;
2008
2083
  if (isFunction(options.hide)) {
2009
2084
  addListener(element, EVENT_HIDE, options.hide, {
2010
2085
  once: true
2011
2086
  });
2012
2087
  }
2013
- if (dispatchEvent(element, EVENT_HIDE) === false || this.destroyed) {
2088
+ if (dispatchEvent(element, EVENT_HIDE, {
2089
+ originalEvent: originalEvent
2090
+ }) === false || this.destroyed) {
2014
2091
  return this;
2015
2092
  }
2016
2093
  if (this.showing) {
@@ -2061,7 +2138,7 @@ var methods = {
2061
2138
  addListener(image, EVENT_TRANSITION_END, onImageTransitionEnd, {
2062
2139
  once: true
2063
2140
  });
2064
- this.zoomTo(0, false, null, null, true);
2141
+ this.zoomTo(0, false, null, true);
2065
2142
  } else {
2066
2143
  onImageTransitionEnd();
2067
2144
  }
@@ -2083,6 +2160,9 @@ var methods = {
2083
2160
  if (this.hiding || this.played || index < 0 || index >= this.length || this.viewed && index === previousIndex) {
2084
2161
  return this;
2085
2162
  }
2163
+ var originalEvent = this.actionEvent || this.viewOriginalEvent || null;
2164
+ this.actionEvent = null;
2165
+ this.viewOriginalEvent = originalEvent;
2086
2166
  if (!this.isShown) {
2087
2167
  this.index = index;
2088
2168
  return this.show();
@@ -2114,7 +2194,8 @@ var methods = {
2114
2194
  if (dispatchEvent(element, EVENT_VIEW, {
2115
2195
  originalImage: this.images[index],
2116
2196
  index: index,
2117
- image: image
2197
+ image: image,
2198
+ originalEvent: originalEvent
2118
2199
  }) === false || !this.isShown || this.hiding || this.played) {
2119
2200
  return this;
2120
2201
  }
@@ -2171,62 +2252,75 @@ var methods = {
2171
2252
  }
2172
2253
  }
2173
2254
  };
2174
- var onLoad;
2175
- var onError;
2176
2255
  addListener(element, EVENT_VIEWED, onViewed, {
2177
2256
  once: true
2178
2257
  });
2179
- this.viewing = {
2180
- abort: function abort() {
2181
- removeListener(element, EVENT_VIEWED, onViewed);
2182
- if (image.complete) {
2183
- if (_this2.imageRendering) {
2184
- _this2.imageRendering.abort();
2185
- } else if (_this2.imageInitializing) {
2186
- _this2.imageInitializing.abort();
2187
- }
2188
- } else {
2189
- // Cancel download to save bandwidth.
2190
- image.src = '';
2191
- removeListener(image, EVENT_LOAD, onLoad);
2192
- if (_this2.timeout) {
2193
- clearTimeout(_this2.timeout);
2194
- }
2195
- }
2196
- }
2197
- };
2198
- if (image.complete) {
2199
- this.load();
2200
- } else {
2201
- addListener(image, EVENT_LOAD, onLoad = function onLoad() {
2202
- removeListener(image, EVENT_ERROR, onError);
2203
- _this2.load();
2204
- }, {
2205
- once: true
2206
- });
2207
- addListener(image, EVENT_ERROR, onError = function onError() {
2258
+ var _loadImage = function loadImage() {
2259
+ var isFallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
2260
+ var onLoad;
2261
+ var onError;
2262
+ var clean = function clean() {
2208
2263
  removeListener(image, EVENT_LOAD, onLoad);
2264
+ removeListener(image, EVENT_ERROR, onError);
2209
2265
  if (_this2.timeout) {
2210
2266
  clearTimeout(_this2.timeout);
2211
2267
  _this2.timeout = false;
2212
2268
  }
2213
- removeClass(image, CLASS_INVISIBLE);
2214
- if (options.loading) {
2215
- removeClass(_this2.canvas, CLASS_LOADING);
2269
+ };
2270
+ _this2.viewing = {
2271
+ abort: function abort() {
2272
+ removeListener(element, EVENT_VIEWED, onViewed);
2273
+ if (image.complete) {
2274
+ if (_this2.imageRendering) {
2275
+ _this2.imageRendering.abort();
2276
+ } else if (_this2.imageInitializing) {
2277
+ _this2.imageInitializing.abort();
2278
+ }
2279
+ } else {
2280
+ // Cancel download to save bandwidth.
2281
+ image.src = '';
2282
+ clean();
2283
+ }
2284
+ }
2285
+ };
2286
+ if (image.complete) {
2287
+ _this2.load();
2288
+ } else {
2289
+ addListener(image, EVENT_LOAD, onLoad = function onLoad() {
2290
+ clean();
2291
+ _this2.load();
2292
+ }, {
2293
+ once: true
2294
+ });
2295
+ addListener(image, EVENT_ERROR, onError = function onError() {
2296
+ clean();
2297
+ if (!isFallback) {
2298
+ var fallbackSrc = img.src;
2299
+ if (fallbackSrc && fallbackSrc !== image.src) {
2300
+ image.src = fallbackSrc;
2301
+ _loadImage(true);
2302
+ return;
2303
+ }
2304
+ }
2305
+ removeClass(image, CLASS_INVISIBLE);
2306
+ if (options.loading) {
2307
+ removeClass(_this2.canvas, CLASS_LOADING);
2308
+ }
2309
+ }, {
2310
+ once: true
2311
+ });
2312
+ if (_this2.timeout) {
2313
+ clearTimeout(_this2.timeout);
2216
2314
  }
2217
- }, {
2218
- once: true
2219
- });
2220
- if (this.timeout) {
2221
- clearTimeout(this.timeout);
2222
- }
2223
2315
 
2224
- // Make the image visible if it fails to load within 1s
2225
- this.timeout = setTimeout(function () {
2226
- removeClass(image, CLASS_INVISIBLE);
2227
- _this2.timeout = false;
2228
- }, 1000);
2229
- }
2316
+ // Make the image visible if it fails to load within 1s
2317
+ _this2.timeout = setTimeout(function () {
2318
+ removeClass(image, CLASS_INVISIBLE);
2319
+ _this2.timeout = false;
2320
+ }, 1000);
2321
+ }
2322
+ };
2323
+ _loadImage();
2230
2324
  return this;
2231
2325
  },
2232
2326
  /**
@@ -2276,13 +2370,11 @@ var methods = {
2276
2370
  * Move the image to an absolute point.
2277
2371
  * @param {number} x - The new position in the horizontal direction.
2278
2372
  * @param {number} [y=x] - The new position in the vertical direction.
2279
- * @param {Event} [_originalEvent=null] - The original event if any.
2280
2373
  * @returns {Viewer} this
2281
2374
  */
2282
2375
  moveTo: function moveTo(x) {
2283
2376
  var _this3 = this;
2284
2377
  var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
2285
- var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2286
2378
  var element = this.element,
2287
2379
  options = this.options,
2288
2380
  imageData = this.imageData;
@@ -2303,6 +2395,8 @@ var methods = {
2303
2395
  y = oldY;
2304
2396
  }
2305
2397
  if (changed) {
2398
+ var originalEvent = this.actionEvent || null;
2399
+ this.actionEvent = null;
2306
2400
  if (isFunction(options.move)) {
2307
2401
  addListener(element, EVENT_MOVE, options.move, {
2308
2402
  once: true
@@ -2313,7 +2407,7 @@ var methods = {
2313
2407
  y: y,
2314
2408
  oldX: oldX,
2315
2409
  oldY: oldY,
2316
- originalEvent: _originalEvent
2410
+ originalEvent: originalEvent
2317
2411
  }) === false) {
2318
2412
  return this;
2319
2413
  }
@@ -2335,7 +2429,7 @@ var methods = {
2335
2429
  y: y,
2336
2430
  oldX: oldX,
2337
2431
  oldY: oldY,
2338
- originalEvent: _originalEvent
2432
+ originalEvent: originalEvent
2339
2433
  }, {
2340
2434
  cancelable: false
2341
2435
  });
@@ -2366,6 +2460,8 @@ var methods = {
2366
2460
  degree = Number(degree);
2367
2461
  if (isNumber(degree) && this.viewed && !this.played && options.rotatable) {
2368
2462
  var oldDegree = imageData.rotate;
2463
+ var originalEvent = this.actionEvent || null;
2464
+ this.actionEvent = null;
2369
2465
  if (isFunction(options.rotate)) {
2370
2466
  addListener(element, EVENT_ROTATE, options.rotate, {
2371
2467
  once: true
@@ -2373,7 +2469,8 @@ var methods = {
2373
2469
  }
2374
2470
  if (dispatchEvent(element, EVENT_ROTATE, {
2375
2471
  degree: degree,
2376
- oldDegree: oldDegree
2472
+ oldDegree: oldDegree,
2473
+ originalEvent: originalEvent
2377
2474
  }) === false) {
2378
2475
  return this;
2379
2476
  }
@@ -2389,7 +2486,8 @@ var methods = {
2389
2486
  }
2390
2487
  dispatchEvent(element, EVENT_ROTATED, {
2391
2488
  degree: degree,
2392
- oldDegree: oldDegree
2489
+ oldDegree: oldDegree,
2490
+ originalEvent: originalEvent
2393
2491
  }, {
2394
2492
  cancelable: false
2395
2493
  });
@@ -2444,6 +2542,8 @@ var methods = {
2444
2542
  scaleY = oldScaleY;
2445
2543
  }
2446
2544
  if (changed) {
2545
+ var originalEvent = this.actionEvent || null;
2546
+ this.actionEvent = null;
2447
2547
  if (isFunction(options.scale)) {
2448
2548
  addListener(element, EVENT_SCALE, options.scale, {
2449
2549
  once: true
@@ -2453,7 +2553,8 @@ var methods = {
2453
2553
  scaleX: scaleX,
2454
2554
  scaleY: scaleY,
2455
2555
  oldScaleX: oldScaleX,
2456
- oldScaleY: oldScaleY
2556
+ oldScaleY: oldScaleY,
2557
+ originalEvent: originalEvent
2457
2558
  }) === false) {
2458
2559
  return this;
2459
2560
  }
@@ -2472,7 +2573,8 @@ var methods = {
2472
2573
  scaleX: scaleX,
2473
2574
  scaleY: scaleY,
2474
2575
  oldScaleX: oldScaleX,
2475
- oldScaleY: oldScaleY
2576
+ oldScaleY: oldScaleY,
2577
+ originalEvent: originalEvent
2476
2578
  }, {
2477
2579
  cancelable: false
2478
2580
  });
@@ -2486,13 +2588,11 @@ var methods = {
2486
2588
  * @param {number} ratio - The target ratio.
2487
2589
  * @param {boolean} [showTooltip=false] - Indicates whether to show the tooltip.
2488
2590
  * @param {Object} [pivot] - The pivot point coordinate for zooming.
2489
- * @param {Event} [_originalEvent=null] - The original event if any.
2490
2591
  * @returns {Viewer} this
2491
2592
  */
2492
2593
  zoom: function zoom(ratio) {
2493
2594
  var showTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2494
2595
  var pivot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2495
- var _originalEvent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
2496
2596
  var imageData = this.imageData;
2497
2597
  ratio = Number(ratio);
2498
2598
  if (ratio < 0) {
@@ -2500,7 +2600,7 @@ var methods = {
2500
2600
  } else {
2501
2601
  ratio = 1 + ratio;
2502
2602
  }
2503
- this.zoomTo(imageData.width * ratio / imageData.naturalWidth, showTooltip, pivot, _originalEvent);
2603
+ this.zoomTo(imageData.width * ratio / imageData.naturalWidth, showTooltip, pivot);
2504
2604
  return this;
2505
2605
  },
2506
2606
  /**
@@ -2508,16 +2608,14 @@ var methods = {
2508
2608
  * @param {number} ratio - The target ratio.
2509
2609
  * @param {boolean} [showTooltip] - Indicates whether to show the tooltip.
2510
2610
  * @param {Object} [pivot] - The pivot point coordinate for zooming.
2511
- * @param {Event} [_originalEvent=null] - The original event if any.
2512
- * @param {Event} [_zoomable=false] - Indicates if the current zoom is available or not.
2611
+ * @param {boolean} [_zoomable=false] - Indicates if the current zoom is available or not.
2513
2612
  * @returns {Viewer} this
2514
2613
  */
2515
2614
  zoomTo: function zoomTo(ratio) {
2516
2615
  var _this6 = this;
2517
2616
  var showTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2518
2617
  var pivot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2519
- var _originalEvent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
2520
- var _zoomable = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
2618
+ var _zoomable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
2521
2619
  var element = this.element,
2522
2620
  options = this.options,
2523
2621
  pointers = this.pointers,
@@ -2535,8 +2633,10 @@ var methods = {
2535
2633
  var maxZoomRatio = Math.min(100, isFunction(options.maxZoomRatio) ? options.maxZoomRatio.call(this, this.image, imageData) : options.maxZoomRatio);
2536
2634
  ratio = Math.min(Math.max(ratio, minZoomRatio), maxZoomRatio);
2537
2635
  }
2538
- if (_originalEvent) {
2539
- switch (_originalEvent.type) {
2636
+ var originalEvent = this.actionEvent || null;
2637
+ this.actionEvent = null;
2638
+ if (originalEvent && originalEvent.type !== EVENT_CLICK) {
2639
+ switch (originalEvent.type) {
2540
2640
  case 'wheel':
2541
2641
  if (options.zoomRatio >= 0.055 && ratio > 0.95 && ratio < 1.05) {
2542
2642
  ratio = 1;
@@ -2564,16 +2664,16 @@ var methods = {
2564
2664
  if (dispatchEvent(element, EVENT_ZOOM, {
2565
2665
  ratio: ratio,
2566
2666
  oldRatio: oldRatio,
2567
- originalEvent: _originalEvent
2667
+ originalEvent: originalEvent
2568
2668
  }) === false) {
2569
2669
  return this;
2570
2670
  }
2571
2671
  this.zooming = true;
2572
- if (_originalEvent) {
2672
+ if (originalEvent && originalEvent.type !== EVENT_CLICK) {
2573
2673
  var offset = getOffset(this.viewer);
2574
2674
  var center = pointers && Object.keys(pointers).length > 0 ? getPointersCenter(pointers) : {
2575
- pageX: _originalEvent.pageX,
2576
- pageY: _originalEvent.pageY
2675
+ pageX: originalEvent.pageX,
2676
+ pageY: originalEvent.pageY
2577
2677
  };
2578
2678
 
2579
2679
  // Zoom from the triggering point of the event
@@ -2604,7 +2704,7 @@ var methods = {
2604
2704
  dispatchEvent(element, EVENT_ZOOMED, {
2605
2705
  ratio: ratio,
2606
2706
  oldRatio: oldRatio,
2607
- originalEvent: _originalEvent
2707
+ originalEvent: originalEvent
2608
2708
  }, {
2609
2709
  cancelable: false
2610
2710
  });
@@ -2628,12 +2728,16 @@ var methods = {
2628
2728
  }
2629
2729
  var element = this.element,
2630
2730
  options = this.options;
2731
+ var originalEvent = this.actionEvent || null;
2732
+ this.actionEvent = null;
2631
2733
  if (isFunction(options.play)) {
2632
2734
  addListener(element, EVENT_PLAY, options.play, {
2633
2735
  once: true
2634
2736
  });
2635
2737
  }
2636
- if (dispatchEvent(element, EVENT_PLAY) === false) {
2738
+ if (dispatchEvent(element, EVENT_PLAY, {
2739
+ originalEvent: originalEvent
2740
+ }) === false) {
2637
2741
  return this;
2638
2742
  }
2639
2743
  var player = this.player;
@@ -2647,6 +2751,7 @@ var methods = {
2647
2751
  this.requestFullscreen(fullscreen);
2648
2752
  }
2649
2753
  addClass(player, CLASS_SHOW);
2754
+ player.removeAttribute('aria-hidden');
2650
2755
  forEach(this.images, function (originalImage, i) {
2651
2756
  var image = document.createElement('img');
2652
2757
  image.src = _this7.getImageURL(originalImage) || originalImage.src;
@@ -2668,17 +2773,51 @@ var methods = {
2668
2773
  if (isNumber(options.interval) && options.interval > 0) {
2669
2774
  var _prev = function prev() {
2670
2775
  clearTimeout(_this7.playing.timeout);
2776
+ var currentOriginalEvent = _this7.actionEvent || null;
2777
+ _this7.actionEvent = null;
2778
+ var prevIndex = index - 1;
2779
+ prevIndex = prevIndex >= 0 ? prevIndex : total - 1;
2780
+ if (isFunction(options.playing)) {
2781
+ addListener(element, EVENT_PLAYING, options.playing, {
2782
+ once: true
2783
+ });
2784
+ }
2785
+ if (dispatchEvent(element, EVENT_PLAYING, {
2786
+ originalImage: _this7.images[prevIndex],
2787
+ index: prevIndex,
2788
+ image: list[prevIndex],
2789
+ originalEvent: currentOriginalEvent
2790
+ }) === false) {
2791
+ _this7.playing.timeout = options.autoplay ? setTimeout(_prev, options.interval) : null;
2792
+ return;
2793
+ }
2671
2794
  removeClass(list[index], CLASS_IN);
2672
- index -= 1;
2673
- index = index >= 0 ? index : total - 1;
2795
+ index = prevIndex;
2674
2796
  addClass(list[index], CLASS_IN);
2675
2797
  _this7.playing.timeout = options.autoplay ? setTimeout(_prev, options.interval) : null;
2676
2798
  };
2677
2799
  var _next = function next() {
2678
2800
  clearTimeout(_this7.playing.timeout);
2801
+ var currentOriginalEvent = _this7.actionEvent || null;
2802
+ _this7.actionEvent = null;
2803
+ var nextIndex = index + 1;
2804
+ nextIndex = nextIndex < total ? nextIndex : 0;
2805
+ if (isFunction(options.playing)) {
2806
+ addListener(element, EVENT_PLAYING, options.playing, {
2807
+ once: true
2808
+ });
2809
+ }
2810
+ if (dispatchEvent(element, EVENT_PLAYING, {
2811
+ originalImage: _this7.images[nextIndex],
2812
+ index: nextIndex,
2813
+ image: list[nextIndex],
2814
+ originalEvent: currentOriginalEvent
2815
+ }) === false) {
2816
+ _this7.playing.timeout = options.autoplay ? setTimeout(_next, options.interval) : null;
2817
+ return;
2818
+ }
2679
2819
  removeClass(list[index], CLASS_IN);
2680
- index += 1;
2681
- index = index < total ? index : 0;
2820
+ index = nextIndex;
2682
2821
  addClass(list[index], CLASS_IN);
2683
2822
  _this7.playing.timeout = options.autoplay ? setTimeout(_next, options.interval) : null;
2684
2823
  };
@@ -2692,7 +2831,10 @@ var methods = {
2692
2831
  }
2693
2832
  return this;
2694
2833
  },
2695
- // Stop play
2834
+ /**
2835
+ * Stop play
2836
+ * @returns {Viewer} this
2837
+ */
2696
2838
  stop: function stop() {
2697
2839
  var _this8 = this;
2698
2840
  if (!this.played) {
@@ -2700,12 +2842,16 @@ var methods = {
2700
2842
  }
2701
2843
  var element = this.element,
2702
2844
  options = this.options;
2845
+ var originalEvent = this.actionEvent || null;
2846
+ this.actionEvent = null;
2703
2847
  if (isFunction(options.stop)) {
2704
2848
  addListener(element, EVENT_STOP, options.stop, {
2705
2849
  once: true
2706
2850
  });
2707
2851
  }
2708
- if (dispatchEvent(element, EVENT_STOP) === false) {
2852
+ if (dispatchEvent(element, EVENT_STOP, {
2853
+ originalEvent: originalEvent
2854
+ }) === false) {
2709
2855
  return this;
2710
2856
  }
2711
2857
  var player = this.player;
@@ -2716,6 +2862,7 @@ var methods = {
2716
2862
  removeListener(image, EVENT_LOAD, _this8.onLoadWhenPlay);
2717
2863
  });
2718
2864
  removeClass(player, CLASS_SHOW);
2865
+ player.setAttribute('aria-hidden', true);
2719
2866
  player.innerHTML = '';
2720
2867
  this.exitFullscreen();
2721
2868
  return this;
@@ -2848,15 +2995,13 @@ var methods = {
2848
2995
  },
2849
2996
  /**
2850
2997
  * Toggle the image size between its current size and natural size
2851
- * @param {Event} [_originalEvent=null] - The original event if any.
2852
2998
  * @returns {Viewer} this
2853
2999
  */
2854
3000
  toggle: function toggle() {
2855
- var _originalEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
2856
3001
  if (this.imageData.ratio === 1) {
2857
- this.zoomTo(this.imageData.oldRatio, true, null, _originalEvent);
3002
+ this.zoomTo(this.imageData.oldRatio, true);
2858
3003
  } else {
2859
- this.zoomTo(1, true, null, _originalEvent);
3004
+ this.zoomTo(1, true);
2860
3005
  }
2861
3006
  return this;
2862
3007
  },
@@ -3071,9 +3216,12 @@ var others = {
3071
3216
  once: true
3072
3217
  });
3073
3218
  }
3074
- if (dispatchEvent(element, EVENT_SHOWN) === false) {
3219
+ if (dispatchEvent(element, EVENT_SHOWN, {
3220
+ originalEvent: this.showOriginalEvent || null
3221
+ }) === false) {
3075
3222
  return;
3076
3223
  }
3224
+ this.showOriginalEvent = null;
3077
3225
  if (this.ready && this.isShown && !this.hiding) {
3078
3226
  this.view(this.index);
3079
3227
  }
@@ -3110,9 +3258,12 @@ var others = {
3110
3258
  once: true
3111
3259
  });
3112
3260
  }
3113
- dispatchEvent(element, EVENT_HIDDEN, null, {
3261
+ dispatchEvent(element, EVENT_HIDDEN, {
3262
+ originalEvent: this.hideOriginalEvent || null
3263
+ }, {
3114
3264
  cancelable: false
3115
3265
  });
3266
+ this.hideOriginalEvent = null;
3116
3267
  }
3117
3268
  },
3118
3269
  requestFullscreen: function requestFullscreen(options) {
@@ -3168,7 +3319,8 @@ var others = {
3168
3319
  case ACTION_MOVE:
3169
3320
  if (offsetX !== 0 || offsetY !== 0) {
3170
3321
  this.pointerMoved = true;
3171
- this.move(offsetX, offsetY, event);
3322
+ this.actionEvent = event;
3323
+ this.move(offsetX, offsetY);
3172
3324
  }
3173
3325
  break;
3174
3326
 
@@ -3177,7 +3329,8 @@ var others = {
3177
3329
  if (options.zoomable && options.zoomOnTouch) {
3178
3330
  var zoomRatio = getMaxZoomRatio(pointers);
3179
3331
  if (zoomRatio !== 0) {
3180
- this.zoom(zoomRatio, false, null, event);
3332
+ this.actionEvent = event;
3333
+ this.zoom(zoomRatio);
3181
3334
  }
3182
3335
  }
3183
3336
  break;
@@ -3187,7 +3340,8 @@ var others = {
3187
3340
  if (options.rotatable && options.rotateOnTouch) {
3188
3341
  var rotateDegree = getMaxRotateDegree(pointers);
3189
3342
  if (rotateDegree !== 0) {
3190
- this.rotate(rotateDegree, event);
3343
+ this.actionEvent = event;
3344
+ this.rotate(rotateDegree);
3191
3345
  }
3192
3346
  }
3193
3347
  break;
@@ -3197,13 +3351,15 @@ var others = {
3197
3351
  if (options.zoomable && options.zoomOnTouch) {
3198
3352
  var _zoomRatio = getMaxZoomRatio(pointers);
3199
3353
  if (_zoomRatio !== 0) {
3200
- this.zoom(_zoomRatio, false, null, event);
3354
+ this.actionEvent = event;
3355
+ this.zoom(_zoomRatio);
3201
3356
  }
3202
3357
  }
3203
3358
  if (options.rotatable && options.rotateOnTouch) {
3204
3359
  var _rotateDegree = getMaxRotateDegree(pointers);
3205
3360
  if (_rotateDegree !== 0) {
3206
- this.rotate(_rotateDegree, event);
3361
+ this.actionEvent = event;
3362
+ this.rotate(_rotateDegree);
3207
3363
  }
3208
3364
  }
3209
3365
  break;
@@ -3214,6 +3370,7 @@ var others = {
3214
3370
  if (absoluteOffsetX > 1 && absoluteOffsetX > Math.abs(offsetY)) {
3215
3371
  // Empty `pointers` as `touchend` event will not be fired after swiped in iOS browsers.
3216
3372
  this.pointers = {};
3373
+ this.actionEvent = event;
3217
3374
  if (offsetX > 1) {
3218
3375
  this.prev(options.loop);
3219
3376
  } else if (offsetX < -1) {
@@ -3260,6 +3417,7 @@ var Viewer = /*#__PURE__*/function () {
3260
3417
  this.ownerDocument = element.ownerDocument || element.host.ownerDocument;
3261
3418
  this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
3262
3419
  this.action = false;
3420
+ this.actionEvent = null;
3263
3421
  this.fading = false;
3264
3422
  this.fulled = false;
3265
3423
  this.hiding = false;
@@ -3373,9 +3531,10 @@ var Viewer = /*#__PURE__*/function () {
3373
3531
  }
3374
3532
  });
3375
3533
  } else {
3376
- addListener(element, EVENT_CLICK, this.onElementClick = function (_ref) {
3377
- var target = _ref.target;
3534
+ addListener(element, EVENT_CLICK, this.onElementClick = function (event) {
3535
+ var target = event.target;
3378
3536
  if (target.localName === 'img' && (!isFunction(options.filter) || options.filter.call(_this, target))) {
3537
+ _this.actionEvent = event;
3379
3538
  _this.view(_this.images.indexOf(target));
3380
3539
  }
3381
3540
  });
@@ -3385,6 +3544,7 @@ var Viewer = /*#__PURE__*/function () {
3385
3544
  if (target.localName === 'img' && (key === 'Enter' || key === ' ')) {
3386
3545
  event.preventDefault();
3387
3546
  if (!isFunction(options.filter) || options.filter.call(_this, target)) {
3547
+ _this.actionEvent = event;
3388
3548
  _this.view(_this.images.indexOf(target));
3389
3549
  }
3390
3550
  }
@@ -3426,6 +3586,9 @@ var Viewer = /*#__PURE__*/function () {
3426
3586
  viewer.id = "".concat(NAMESPACE).concat(this.id);
3427
3587
  title.id = "".concat(NAMESPACE, "Title").concat(this.id);
3428
3588
  addClass(title, !options.title ? CLASS_HIDE : getResponsiveClass(Array.isArray(options.title) ? options.title[0] : options.title));
3589
+ if (options.title) {
3590
+ title.removeAttribute('aria-hidden');
3591
+ }
3429
3592
  var navbarOptions = isPlainObject(options.navbar) ? options.navbar : {};
3430
3593
  var navbarShow = options.navbar;
3431
3594
  var navbarSize = !isUndefined(navbarOptions.size) ? navbarOptions.size : options.navbar;
@@ -3433,6 +3596,9 @@ var Viewer = /*#__PURE__*/function () {
3433
3596
  navbarShow = !isUndefined(navbarOptions.show) ? navbarOptions.show : true;
3434
3597
  }
3435
3598
  addClass(navbar, !navbarShow ? CLASS_HIDE : getResponsiveClass(navbarShow));
3599
+ if (navbarShow) {
3600
+ navbar.removeAttribute('aria-hidden');
3601
+ }
3436
3602
  if (['small', 'medium', 'large'].indexOf(navbarSize) !== -1) {
3437
3603
  addClass(navbar, "".concat(NAMESPACE, "-").concat(navbarSize));
3438
3604
  }
@@ -3454,7 +3620,13 @@ var Viewer = /*#__PURE__*/function () {
3454
3620
  } else {
3455
3621
  addClass(navigation, !options.navigation ? CLASS_HIDE : getResponsiveClass(options.navigation));
3456
3622
  }
3623
+ if (options.navigation) {
3624
+ navigation.removeAttribute('aria-hidden');
3625
+ }
3457
3626
  toggleClass(button, CLASS_HIDE, !options.button);
3627
+ if (options.button) {
3628
+ button.removeAttribute('aria-hidden');
3629
+ }
3458
3630
  if (options.keyboard) {
3459
3631
  button.setAttribute('tabindex', 0);
3460
3632
  forEach(navigation.querySelectorAll('[role="button"]'), function (item) {
@@ -3482,6 +3654,7 @@ var Viewer = /*#__PURE__*/function () {
3482
3654
  if (!custom) {
3483
3655
  addClass(toolbar, getResponsiveClass(options.toolbar));
3484
3656
  }
3657
+ toolbar.removeAttribute('aria-hidden');
3485
3658
  forEach(custom ? options.toolbar : BUTTONS, function (value, index) {
3486
3659
  var deep = custom && isPlainObject(value);
3487
3660
  var name = custom ? hyphenate(index) : value;
@@ -3517,6 +3690,11 @@ var Viewer = /*#__PURE__*/function () {
3517
3690
  } else {
3518
3691
  addClass(toolbar, CLASS_HIDE);
3519
3692
  }
3693
+ if (options.title || navbarShow || options.toolbar) {
3694
+ this.footer.removeAttribute('aria-hidden');
3695
+ } else {
3696
+ addClass(this.footer, CLASS_HIDE);
3697
+ }
3520
3698
  if (!options.rotatable) {
3521
3699
  var rotates = toolbar.querySelectorAll('li[class*="rotate"]');
3522
3700
  addClass(rotates, CLASS_INVISIBLE);