Issues (141)

resources/bootstrap/js/carousel.js (1 issue)

1
/*!
2
  * Bootstrap carousel.js v4.6.2 (https://getbootstrap.com/)
3
  * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
  */
6
(function (global, factory) {
7
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) :
8
  typeof define === 'function' && define.amd ? define(['jquery', './util'], factory) :
9
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Carousel = factory(global.jQuery, global.Util));
10
})(this, (function ($, Util) { 'use strict';
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
14
  var $__default = /*#__PURE__*/_interopDefaultLegacy($);
15
  var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util);
16
17
  function _defineProperties(target, props) {
18
    for (var i = 0; i < props.length; i++) {
19
      var descriptor = props[i];
20
      descriptor.enumerable = descriptor.enumerable || false;
21
      descriptor.configurable = true;
22
      if ("value" in descriptor) descriptor.writable = true;
23
      Object.defineProperty(target, descriptor.key, descriptor);
24
    }
25
  }
26
27
  function _createClass(Constructor, protoProps, staticProps) {
28
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
29
    if (staticProps) _defineProperties(Constructor, staticProps);
30
    Object.defineProperty(Constructor, "prototype", {
31
      writable: false
32
    });
33
    return Constructor;
34
  }
35
36
  function _extends() {
37
    _extends = Object.assign ? Object.assign.bind() : function (target) {
38
      for (var i = 1; i < arguments.length; i++) {
39
        var source = arguments[i];
40
41
        for (var key in source) {
0 ignored issues
show
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
42
          if (Object.prototype.hasOwnProperty.call(source, key)) {
43
            target[key] = source[key];
44
          }
45
        }
46
      }
47
48
      return target;
49
    };
50
    return _extends.apply(this, arguments);
51
  }
52
53
  /**
54
   * Constants
55
   */
56
57
  var NAME = 'carousel';
58
  var VERSION = '4.6.2';
59
  var DATA_KEY = 'bs.carousel';
60
  var EVENT_KEY = "." + DATA_KEY;
61
  var DATA_API_KEY = '.data-api';
62
  var JQUERY_NO_CONFLICT = $__default["default"].fn[NAME];
63
  var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key
64
65
  var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key
66
67
  var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
68
69
  var SWIPE_THRESHOLD = 40;
70
  var CLASS_NAME_CAROUSEL = 'carousel';
71
  var CLASS_NAME_ACTIVE = 'active';
72
  var CLASS_NAME_SLIDE = 'slide';
73
  var CLASS_NAME_RIGHT = 'carousel-item-right';
74
  var CLASS_NAME_LEFT = 'carousel-item-left';
75
  var CLASS_NAME_NEXT = 'carousel-item-next';
76
  var CLASS_NAME_PREV = 'carousel-item-prev';
77
  var CLASS_NAME_POINTER_EVENT = 'pointer-event';
78
  var DIRECTION_NEXT = 'next';
79
  var DIRECTION_PREV = 'prev';
80
  var DIRECTION_LEFT = 'left';
81
  var DIRECTION_RIGHT = 'right';
82
  var EVENT_SLIDE = "slide" + EVENT_KEY;
83
  var EVENT_SLID = "slid" + EVENT_KEY;
84
  var EVENT_KEYDOWN = "keydown" + EVENT_KEY;
85
  var EVENT_MOUSEENTER = "mouseenter" + EVENT_KEY;
86
  var EVENT_MOUSELEAVE = "mouseleave" + EVENT_KEY;
87
  var EVENT_TOUCHSTART = "touchstart" + EVENT_KEY;
88
  var EVENT_TOUCHMOVE = "touchmove" + EVENT_KEY;
89
  var EVENT_TOUCHEND = "touchend" + EVENT_KEY;
90
  var EVENT_POINTERDOWN = "pointerdown" + EVENT_KEY;
91
  var EVENT_POINTERUP = "pointerup" + EVENT_KEY;
92
  var EVENT_DRAG_START = "dragstart" + EVENT_KEY;
93
  var EVENT_LOAD_DATA_API = "load" + EVENT_KEY + DATA_API_KEY;
94
  var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY;
95
  var SELECTOR_ACTIVE = '.active';
96
  var SELECTOR_ACTIVE_ITEM = '.active.carousel-item';
97
  var SELECTOR_ITEM = '.carousel-item';
98
  var SELECTOR_ITEM_IMG = '.carousel-item img';
99
  var SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';
100
  var SELECTOR_INDICATORS = '.carousel-indicators';
101
  var SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]';
102
  var SELECTOR_DATA_RIDE = '[data-ride="carousel"]';
103
  var Default = {
104
    interval: 5000,
105
    keyboard: true,
106
    slide: false,
107
    pause: 'hover',
108
    wrap: true,
109
    touch: true
110
  };
111
  var DefaultType = {
112
    interval: '(number|boolean)',
113
    keyboard: 'boolean',
114
    slide: '(boolean|string)',
115
    pause: '(string|boolean)',
116
    wrap: 'boolean',
117
    touch: 'boolean'
118
  };
119
  var PointerType = {
120
    TOUCH: 'touch',
121
    PEN: 'pen'
122
  };
123
  /**
124
   * Class definition
125
   */
126
127
  var Carousel = /*#__PURE__*/function () {
128
    function Carousel(element, config) {
129
      this._items = null;
130
      this._interval = null;
131
      this._activeElement = null;
132
      this._isPaused = false;
133
      this._isSliding = false;
134
      this.touchTimeout = null;
135
      this.touchStartX = 0;
136
      this.touchDeltaX = 0;
137
      this._config = this._getConfig(config);
138
      this._element = element;
139
      this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS);
140
      this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
141
      this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent);
142
143
      this._addEventListeners();
144
    } // Getters
145
146
147
    var _proto = Carousel.prototype;
148
149
    // Public
150
    _proto.next = function next() {
151
      if (!this._isSliding) {
152
        this._slide(DIRECTION_NEXT);
153
      }
154
    };
155
156
    _proto.nextWhenVisible = function nextWhenVisible() {
157
      var $element = $__default["default"](this._element); // Don't call next when the page isn't visible
158
      // or the carousel or its parent isn't visible
159
160
      if (!document.hidden && $element.is(':visible') && $element.css('visibility') !== 'hidden') {
161
        this.next();
162
      }
163
    };
164
165
    _proto.prev = function prev() {
166
      if (!this._isSliding) {
167
        this._slide(DIRECTION_PREV);
168
      }
169
    };
170
171
    _proto.pause = function pause(event) {
172
      if (!event) {
173
        this._isPaused = true;
174
      }
175
176
      if (this._element.querySelector(SELECTOR_NEXT_PREV)) {
177
        Util__default["default"].triggerTransitionEnd(this._element);
178
        this.cycle(true);
179
      }
180
181
      clearInterval(this._interval);
182
      this._interval = null;
183
    };
184
185
    _proto.cycle = function cycle(event) {
186
      if (!event) {
187
        this._isPaused = false;
188
      }
189
190
      if (this._interval) {
191
        clearInterval(this._interval);
192
        this._interval = null;
193
      }
194
195
      if (this._config.interval && !this._isPaused) {
196
        this._updateInterval();
197
198
        this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);
199
      }
200
    };
201
202
    _proto.to = function to(index) {
203
      var _this = this;
204
205
      this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM);
206
207
      var activeIndex = this._getItemIndex(this._activeElement);
208
209
      if (index > this._items.length - 1 || index < 0) {
210
        return;
211
      }
212
213
      if (this._isSliding) {
214
        $__default["default"](this._element).one(EVENT_SLID, function () {
215
          return _this.to(index);
216
        });
217
        return;
218
      }
219
220
      if (activeIndex === index) {
221
        this.pause();
222
        this.cycle();
223
        return;
224
      }
225
226
      var direction = index > activeIndex ? DIRECTION_NEXT : DIRECTION_PREV;
227
228
      this._slide(direction, this._items[index]);
229
    };
230
231
    _proto.dispose = function dispose() {
232
      $__default["default"](this._element).off(EVENT_KEY);
233
      $__default["default"].removeData(this._element, DATA_KEY);
234
      this._items = null;
235
      this._config = null;
236
      this._element = null;
237
      this._interval = null;
238
      this._isPaused = null;
239
      this._isSliding = null;
240
      this._activeElement = null;
241
      this._indicatorsElement = null;
242
    } // Private
243
    ;
244
245
    _proto._getConfig = function _getConfig(config) {
246
      config = _extends({}, Default, config);
247
      Util__default["default"].typeCheckConfig(NAME, config, DefaultType);
248
      return config;
249
    };
250
251
    _proto._handleSwipe = function _handleSwipe() {
252
      var absDeltax = Math.abs(this.touchDeltaX);
253
254
      if (absDeltax <= SWIPE_THRESHOLD) {
255
        return;
256
      }
257
258
      var direction = absDeltax / this.touchDeltaX;
259
      this.touchDeltaX = 0; // swipe left
260
261
      if (direction > 0) {
262
        this.prev();
263
      } // swipe right
264
265
266
      if (direction < 0) {
267
        this.next();
268
      }
269
    };
270
271
    _proto._addEventListeners = function _addEventListeners() {
272
      var _this2 = this;
273
274
      if (this._config.keyboard) {
275
        $__default["default"](this._element).on(EVENT_KEYDOWN, function (event) {
276
          return _this2._keydown(event);
277
        });
278
      }
279
280
      if (this._config.pause === 'hover') {
281
        $__default["default"](this._element).on(EVENT_MOUSEENTER, function (event) {
282
          return _this2.pause(event);
283
        }).on(EVENT_MOUSELEAVE, function (event) {
284
          return _this2.cycle(event);
285
        });
286
      }
287
288
      if (this._config.touch) {
289
        this._addTouchEventListeners();
290
      }
291
    };
292
293
    _proto._addTouchEventListeners = function _addTouchEventListeners() {
294
      var _this3 = this;
295
296
      if (!this._touchSupported) {
297
        return;
298
      }
299
300
      var start = function start(event) {
301
        if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
302
          _this3.touchStartX = event.originalEvent.clientX;
303
        } else if (!_this3._pointerEvent) {
304
          _this3.touchStartX = event.originalEvent.touches[0].clientX;
305
        }
306
      };
307
308
      var move = function move(event) {
309
        // ensure swiping with one touch and not pinching
310
        _this3.touchDeltaX = event.originalEvent.touches && event.originalEvent.touches.length > 1 ? 0 : event.originalEvent.touches[0].clientX - _this3.touchStartX;
311
      };
312
313
      var end = function end(event) {
314
        if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
315
          _this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX;
316
        }
317
318
        _this3._handleSwipe();
319
320
        if (_this3._config.pause === 'hover') {
321
          // If it's a touch-enabled device, mouseenter/leave are fired as
322
          // part of the mouse compatibility events on first tap - the carousel
323
          // would stop cycling until user tapped out of it;
324
          // here, we listen for touchend, explicitly pause the carousel
325
          // (as if it's the second time we tap on it, mouseenter compat event
326
          // is NOT fired) and after a timeout (to allow for mouse compatibility
327
          // events to fire) we explicitly restart cycling
328
          _this3.pause();
329
330
          if (_this3.touchTimeout) {
331
            clearTimeout(_this3.touchTimeout);
332
          }
333
334
          _this3.touchTimeout = setTimeout(function (event) {
335
            return _this3.cycle(event);
336
          }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval);
337
        }
338
      };
339
340
      $__default["default"](this._element.querySelectorAll(SELECTOR_ITEM_IMG)).on(EVENT_DRAG_START, function (e) {
341
        return e.preventDefault();
342
      });
343
344
      if (this._pointerEvent) {
345
        $__default["default"](this._element).on(EVENT_POINTERDOWN, function (event) {
346
          return start(event);
347
        });
348
        $__default["default"](this._element).on(EVENT_POINTERUP, function (event) {
349
          return end(event);
350
        });
351
352
        this._element.classList.add(CLASS_NAME_POINTER_EVENT);
353
      } else {
354
        $__default["default"](this._element).on(EVENT_TOUCHSTART, function (event) {
355
          return start(event);
356
        });
357
        $__default["default"](this._element).on(EVENT_TOUCHMOVE, function (event) {
358
          return move(event);
359
        });
360
        $__default["default"](this._element).on(EVENT_TOUCHEND, function (event) {
361
          return end(event);
362
        });
363
      }
364
    };
365
366
    _proto._keydown = function _keydown(event) {
367
      if (/input|textarea/i.test(event.target.tagName)) {
368
        return;
369
      }
370
371
      switch (event.which) {
372
        case ARROW_LEFT_KEYCODE:
373
          event.preventDefault();
374
          this.prev();
375
          break;
376
377
        case ARROW_RIGHT_KEYCODE:
378
          event.preventDefault();
379
          this.next();
380
          break;
381
      }
382
    };
383
384
    _proto._getItemIndex = function _getItemIndex(element) {
385
      this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) : [];
386
      return this._items.indexOf(element);
387
    };
388
389
    _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) {
390
      var isNextDirection = direction === DIRECTION_NEXT;
391
      var isPrevDirection = direction === DIRECTION_PREV;
392
393
      var activeIndex = this._getItemIndex(activeElement);
394
395
      var lastItemIndex = this._items.length - 1;
396
      var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;
397
398
      if (isGoingToWrap && !this._config.wrap) {
399
        return activeElement;
400
      }
401
402
      var delta = direction === DIRECTION_PREV ? -1 : 1;
403
      var itemIndex = (activeIndex + delta) % this._items.length;
404
      return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
405
    };
406
407
    _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) {
408
      var targetIndex = this._getItemIndex(relatedTarget);
409
410
      var fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM));
411
412
      var slideEvent = $__default["default"].Event(EVENT_SLIDE, {
413
        relatedTarget: relatedTarget,
414
        direction: eventDirectionName,
415
        from: fromIndex,
416
        to: targetIndex
417
      });
418
      $__default["default"](this._element).trigger(slideEvent);
419
      return slideEvent;
420
    };
421
422
    _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) {
423
      if (this._indicatorsElement) {
424
        var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE));
425
        $__default["default"](indicators).removeClass(CLASS_NAME_ACTIVE);
426
427
        var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
428
429
        if (nextIndicator) {
430
          $__default["default"](nextIndicator).addClass(CLASS_NAME_ACTIVE);
431
        }
432
      }
433
    };
434
435
    _proto._updateInterval = function _updateInterval() {
436
      var element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM);
437
438
      if (!element) {
439
        return;
440
      }
441
442
      var elementInterval = parseInt(element.getAttribute('data-interval'), 10);
443
444
      if (elementInterval) {
445
        this._config.defaultInterval = this._config.defaultInterval || this._config.interval;
446
        this._config.interval = elementInterval;
447
      } else {
448
        this._config.interval = this._config.defaultInterval || this._config.interval;
449
      }
450
    };
451
452
    _proto._slide = function _slide(direction, element) {
453
      var _this4 = this;
454
455
      var activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM);
456
457
      var activeElementIndex = this._getItemIndex(activeElement);
458
459
      var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
460
461
      var nextElementIndex = this._getItemIndex(nextElement);
462
463
      var isCycling = Boolean(this._interval);
464
      var directionalClassName;
465
      var orderClassName;
466
      var eventDirectionName;
467
468
      if (direction === DIRECTION_NEXT) {
469
        directionalClassName = CLASS_NAME_LEFT;
470
        orderClassName = CLASS_NAME_NEXT;
471
        eventDirectionName = DIRECTION_LEFT;
472
      } else {
473
        directionalClassName = CLASS_NAME_RIGHT;
474
        orderClassName = CLASS_NAME_PREV;
475
        eventDirectionName = DIRECTION_RIGHT;
476
      }
477
478
      if (nextElement && $__default["default"](nextElement).hasClass(CLASS_NAME_ACTIVE)) {
479
        this._isSliding = false;
480
        return;
481
      }
482
483
      var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
484
485
      if (slideEvent.isDefaultPrevented()) {
486
        return;
487
      }
488
489
      if (!activeElement || !nextElement) {
490
        // Some weirdness is happening, so we bail
491
        return;
492
      }
493
494
      this._isSliding = true;
495
496
      if (isCycling) {
497
        this.pause();
498
      }
499
500
      this._setActiveIndicatorElement(nextElement);
501
502
      this._activeElement = nextElement;
503
      var slidEvent = $__default["default"].Event(EVENT_SLID, {
504
        relatedTarget: nextElement,
505
        direction: eventDirectionName,
506
        from: activeElementIndex,
507
        to: nextElementIndex
508
      });
509
510
      if ($__default["default"](this._element).hasClass(CLASS_NAME_SLIDE)) {
511
        $__default["default"](nextElement).addClass(orderClassName);
512
        Util__default["default"].reflow(nextElement);
513
        $__default["default"](activeElement).addClass(directionalClassName);
514
        $__default["default"](nextElement).addClass(directionalClassName);
515
        var transitionDuration = Util__default["default"].getTransitionDurationFromElement(activeElement);
516
        $__default["default"](activeElement).one(Util__default["default"].TRANSITION_END, function () {
517
          $__default["default"](nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(CLASS_NAME_ACTIVE);
518
          $__default["default"](activeElement).removeClass(CLASS_NAME_ACTIVE + " " + orderClassName + " " + directionalClassName);
519
          _this4._isSliding = false;
520
          setTimeout(function () {
521
            return $__default["default"](_this4._element).trigger(slidEvent);
522
          }, 0);
523
        }).emulateTransitionEnd(transitionDuration);
524
      } else {
525
        $__default["default"](activeElement).removeClass(CLASS_NAME_ACTIVE);
526
        $__default["default"](nextElement).addClass(CLASS_NAME_ACTIVE);
527
        this._isSliding = false;
528
        $__default["default"](this._element).trigger(slidEvent);
529
      }
530
531
      if (isCycling) {
532
        this.cycle();
533
      }
534
    } // Static
535
    ;
536
537
    Carousel._jQueryInterface = function _jQueryInterface(config) {
538
      return this.each(function () {
539
        var data = $__default["default"](this).data(DATA_KEY);
540
541
        var _config = _extends({}, Default, $__default["default"](this).data());
542
543
        if (typeof config === 'object') {
544
          _config = _extends({}, _config, config);
545
        }
546
547
        var action = typeof config === 'string' ? config : _config.slide;
548
549
        if (!data) {
550
          data = new Carousel(this, _config);
551
          $__default["default"](this).data(DATA_KEY, data);
552
        }
553
554
        if (typeof config === 'number') {
555
          data.to(config);
556
        } else if (typeof action === 'string') {
557
          if (typeof data[action] === 'undefined') {
558
            throw new TypeError("No method named \"" + action + "\"");
559
          }
560
561
          data[action]();
562
        } else if (_config.interval && _config.ride) {
563
          data.pause();
564
          data.cycle();
565
        }
566
      });
567
    };
568
569
    Carousel._dataApiClickHandler = function _dataApiClickHandler(event) {
570
      var selector = Util__default["default"].getSelectorFromElement(this);
571
572
      if (!selector) {
573
        return;
574
      }
575
576
      var target = $__default["default"](selector)[0];
577
578
      if (!target || !$__default["default"](target).hasClass(CLASS_NAME_CAROUSEL)) {
579
        return;
580
      }
581
582
      var config = _extends({}, $__default["default"](target).data(), $__default["default"](this).data());
583
584
      var slideIndex = this.getAttribute('data-slide-to');
585
586
      if (slideIndex) {
587
        config.interval = false;
588
      }
589
590
      Carousel._jQueryInterface.call($__default["default"](target), config);
591
592
      if (slideIndex) {
593
        $__default["default"](target).data(DATA_KEY).to(slideIndex);
594
      }
595
596
      event.preventDefault();
597
    };
598
599
    _createClass(Carousel, null, [{
600
      key: "VERSION",
601
      get: function get() {
602
        return VERSION;
603
      }
604
    }, {
605
      key: "Default",
606
      get: function get() {
607
        return Default;
608
      }
609
    }]);
610
611
    return Carousel;
612
  }();
613
  /**
614
   * Data API implementation
615
   */
616
617
618
  $__default["default"](document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler);
619
  $__default["default"](window).on(EVENT_LOAD_DATA_API, function () {
620
    var carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE));
621
622
    for (var i = 0, len = carousels.length; i < len; i++) {
623
      var $carousel = $__default["default"](carousels[i]);
624
625
      Carousel._jQueryInterface.call($carousel, $carousel.data());
626
    }
627
  });
628
  /**
629
   * jQuery
630
   */
631
632
  $__default["default"].fn[NAME] = Carousel._jQueryInterface;
633
  $__default["default"].fn[NAME].Constructor = Carousel;
634
635
  $__default["default"].fn[NAME].noConflict = function () {
636
    $__default["default"].fn[NAME] = JQUERY_NO_CONFLICT;
637
    return Carousel._jQueryInterface;
638
  };
639
640
  return Carousel;
641
642
}));
643
//# sourceMappingURL=carousel.js.map
644