/** * SimpleBar.js - v5.1.0 * Scrollbars, simpler. * https://grsmto.github.io/simplebar/ * * Made by Adrien Denat from a fork by Jonathan Nicol * Under MIT License */ import 'core-js/modules/es.array.for-each'; import 'core-js/modules/web.dom-collections.for-each'; import canUseDOM from 'can-use-dom'; import 'core-js/modules/es.array.filter'; import 'core-js/modules/es.array.iterator'; import 'core-js/modules/es.object.assign'; import 'core-js/modules/es.object.to-string'; import 'core-js/modules/es.parse-int'; import 'core-js/modules/es.string.iterator'; import 'core-js/modules/es.weak-map'; import 'core-js/modules/web.dom-collections.iterator'; import throttle from 'lodash.throttle'; import debounce from 'lodash.debounce'; import memoize from 'lodash.memoize'; import ResizeObserver from 'resize-observer-polyfill'; import 'core-js/modules/es.array.reduce'; import 'core-js/modules/es.function.name'; import 'core-js/modules/es.regexp.exec'; import 'core-js/modules/es.string.match'; import 'core-js/modules/es.string.replace'; var cachedScrollbarWidth = null; var cachedDevicePixelRatio = null; if (canUseDOM) { window.addEventListener('resize', function () { if (cachedDevicePixelRatio !== window.devicePixelRatio) { cachedDevicePixelRatio = window.devicePixelRatio; cachedScrollbarWidth = null; } }); } function scrollbarWidth() { if (cachedScrollbarWidth === null) { if (typeof document === 'undefined') { cachedScrollbarWidth = 0; return cachedScrollbarWidth; } var body = document.body; var box = document.createElement('div'); box.classList.add('simplebar-hide-scrollbar'); body.appendChild(box); var width = box.getBoundingClientRect().right; body.removeChild(box); cachedScrollbarWidth = width; } return cachedScrollbarWidth; } // Helper function to retrieve options from element attributes var getOptions = function getOptions(obj) { var options = Array.prototype.reduce.call(obj, function (acc, attribute) { var option = attribute.name.match(/data-simplebar-(.+)/); if (option) { var key = option[1].replace(/\W+(.)/g, function (x, chr) { return chr.toUpperCase(); }); switch (attribute.value) { case 'true': acc[key] = true; break; case 'false': acc[key] = false; break; case undefined: acc[key] = true; break; default: acc[key] = attribute.value; } } return acc; }, {}); return options; }; function getElementWindow(element) { if (!element || !element.ownerDocument || !element.ownerDocument.defaultView) { return window; } return element.ownerDocument.defaultView; } function getElementDocument(element) { if (!element || !element.ownerDocument) { return document; } return element.ownerDocument; } var SimpleBar = /*#__PURE__*/ function () { function SimpleBar(element, options) { var _this = this; this.onScroll = function () { var elWindow = getElementWindow(_this.el); if (!_this.scrollXTicking) { elWindow.requestAnimationFrame(_this.scrollX); _this.scrollXTicking = true; } if (!_this.scrollYTicking) { elWindow.requestAnimationFrame(_this.scrollY); _this.scrollYTicking = true; } }; this.scrollX = function () { if (_this.axis.x.isOverflowing) { _this.showScrollbar('x'); _this.positionScrollbar('x'); } _this.scrollXTicking = false; }; this.scrollY = function () { if (_this.axis.y.isOverflowing) { _this.showScrollbar('y'); _this.positionScrollbar('y'); } _this.scrollYTicking = false; }; this.onMouseEnter = function () { _this.showScrollbar('x'); _this.showScrollbar('y'); }; this.onMouseMove = function (e) { _this.mouseX = e.clientX; _this.mouseY = e.clientY; if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) { _this.onMouseMoveForAxis('x'); } if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) { _this.onMouseMoveForAxis('y'); } }; this.onMouseLeave = function () { _this.onMouseMove.cancel(); if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) { _this.onMouseLeaveForAxis('x'); } if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) { _this.onMouseLeaveForAxis('y'); } _this.mouseX = -1; _this.mouseY = -1; }; this.onWindowResize = function () { // Recalculate scrollbarWidth in case it's a zoom _this.scrollbarWidth = _this.getScrollbarWidth(); _this.hideNativeScrollbar(); }; this.hideScrollbars = function () { _this.axis.x.track.rect = _this.axis.x.track.el.getBoundingClientRect(); _this.axis.y.track.rect = _this.axis.y.track.el.getBoundingClientRect(); if (!_this.isWithinBounds(_this.axis.y.track.rect)) { _this.axis.y.scrollbar.el.classList.remove(_this.classNames.visible); _this.axis.y.isVisible = false; } if (!_this.isWithinBounds(_this.axis.x.track.rect)) { _this.axis.x.scrollbar.el.classList.remove(_this.classNames.visible); _this.axis.x.isVisible = false; } }; this.onPointerEvent = function (e) { var isWithinTrackXBounds, isWithinTrackYBounds; _this.axis.x.track.rect = _this.axis.x.track.el.getBoundingClientRect(); _this.axis.y.track.rect = _this.axis.y.track.el.getBoundingClientRect(); if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) { isWithinTrackXBounds = _this.isWithinBounds(_this.axis.x.track.rect); } if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) { isWithinTrackYBounds = _this.isWithinBounds(_this.axis.y.track.rect); } // If any pointer event is called on the scrollbar if (isWithinTrackXBounds || isWithinTrackYBounds) { // Preventing the event's default action stops text being // selectable during the drag. e.preventDefault(); // Prevent event leaking e.stopPropagation(); if (e.type === 'mousedown') { if (isWithinTrackXBounds) { _this.axis.x.scrollbar.rect = _this.axis.x.scrollbar.el.getBoundingClientRect(); if (_this.isWithinBounds(_this.axis.x.scrollbar.rect)) { _this.onDragStart(e, 'x'); } else { _this.onTrackClick(e, 'x'); } } if (isWithinTrackYBounds) { _this.axis.y.scrollbar.rect = _this.axis.y.scrollbar.el.getBoundingClientRect(); if (_this.isWithinBounds(_this.axis.y.scrollbar.rect)) { _this.onDragStart(e, 'y'); } else { _this.onTrackClick(e, 'y'); } } } } }; this.drag = function (e) { var eventOffset; var track = _this.axis[_this.draggedAxis].track; var trackSize = track.rect[_this.axis[_this.draggedAxis].sizeAttr]; var scrollbar = _this.axis[_this.draggedAxis].scrollbar; var contentSize = _this.contentWrapperEl[_this.axis[_this.draggedAxis].scrollSizeAttr]; var hostSize = parseInt(_this.elStyles[_this.axis[_this.draggedAxis].sizeAttr], 10); e.preventDefault(); e.stopPropagation(); if (_this.draggedAxis === 'y') { eventOffset = e.pageY; } else { eventOffset = e.pageX; } // Calculate how far the user's mouse is from the top/left of the scrollbar (minus the dragOffset). var dragPos = eventOffset - track.rect[_this.axis[_this.draggedAxis].offsetAttr] - _this.axis[_this.draggedAxis].dragOffset; // Convert the mouse position into a percentage of the scrollbar height/width. var dragPerc = dragPos / (trackSize - scrollbar.size); // Scroll the content by the same percentage. var scrollPos = dragPerc * (contentSize - hostSize); // Fix browsers inconsistency on RTL if (_this.draggedAxis === 'x') { scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? scrollPos - (trackSize + scrollbar.size) : scrollPos; scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollPos : scrollPos; } _this.contentWrapperEl[_this.axis[_this.draggedAxis].scrollOffsetAttr] = scrollPos; }; this.onEndDrag = function (e) { var elDocument = getElementDocument(_this.el); var elWindow = getElementWindow(_this.el); e.preventDefault(); e.stopPropagation(); _this.el.classList.remove(_this.classNames.dragging); elDocument.removeEventListener('mousemove', _this.drag, true); elDocument.removeEventListener('mouseup', _this.onEndDrag, true); _this.removePreventClickId = elWindow.setTimeout(function () { // Remove these asynchronously so we still suppress click events // generated simultaneously with mouseup. elDocument.removeEventListener('click', _this.preventClick, true); elDocument.removeEventListener('dblclick', _this.preventClick, true); _this.removePreventClickId = null; }); }; this.preventClick = function (e) { e.preventDefault(); e.stopPropagation(); }; this.el = element; this.minScrollbarWidth = 20; this.options = Object.assign({}, SimpleBar.defaultOptions, {}, options); this.classNames = Object.assign({}, SimpleBar.defaultOptions.classNames, {}, this.options.classNames); this.axis = { x: { scrollOffsetAttr: 'scrollLeft', sizeAttr: 'width', scrollSizeAttr: 'scrollWidth', offsetSizeAttr: 'offsetWidth', offsetAttr: 'left', overflowAttr: 'overflowX', dragOffset: 0, isOverflowing: true, isVisible: false, forceVisible: false, track: {}, scrollbar: {} }, y: { scrollOffsetAttr: 'scrollTop', sizeAttr: 'height', scrollSizeAttr: 'scrollHeight', offsetSizeAttr: 'offsetHeight', offsetAttr: 'top', overflowAttr: 'overflowY', dragOffset: 0, isOverflowing: true, isVisible: false, forceVisible: false, track: {}, scrollbar: {} } }; this.removePreventClickId = null; // Don't re-instantiate over an existing one if (SimpleBar.instances.has(this.el)) { return; } this.recalculate = throttle(this.recalculate.bind(this), 64); this.onMouseMove = throttle(this.onMouseMove.bind(this), 64); this.hideScrollbars = debounce(this.hideScrollbars.bind(this), this.options.timeout); this.onWindowResize = debounce(this.onWindowResize.bind(this), 64, { leading: true }); SimpleBar.getRtlHelpers = memoize(SimpleBar.getRtlHelpers); this.init(); } /** * Static properties */ /** * Helper to fix browsers inconsistency on RTL: * - Firefox inverts the scrollbar initial position * - IE11 inverts both scrollbar position and scrolling offset * Directly inspired by @KingSora's OverlayScrollbars https://github.com/KingSora/OverlayScrollbars/blob/master/js/OverlayScrollbars.js#L1634 */ SimpleBar.getRtlHelpers = function getRtlHelpers() { var dummyDiv = document.createElement('div'); dummyDiv.innerHTML = '
'; var scrollbarDummyEl = dummyDiv.firstElementChild; document.body.appendChild(scrollbarDummyEl); var dummyContainerChild = scrollbarDummyEl.firstElementChild; scrollbarDummyEl.scrollLeft = 0; var dummyContainerOffset = SimpleBar.getOffset(scrollbarDummyEl); var dummyContainerChildOffset = SimpleBar.getOffset(dummyContainerChild); scrollbarDummyEl.scrollLeft = 999; var dummyContainerScrollOffsetAfterScroll = SimpleBar.getOffset(dummyContainerChild); return { // determines if the scrolling is responding with negative values isRtlScrollingInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left && dummyContainerChildOffset.left - dummyContainerScrollOffsetAfterScroll.left !== 0, // determines if the origin scrollbar position is inverted or not (positioned on left or right) isRtlScrollbarInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left }; }; SimpleBar.getOffset = function getOffset(el) { var rect = el.getBoundingClientRect(); var elDocument = getElementDocument(el); var elWindow = getElementWindow(el); return { top: rect.top + (elWindow.pageYOffset || elDocument.documentElement.scrollTop), left: rect.left + (elWindow.pageXOffset || elDocument.documentElement.scrollLeft) }; }; var _proto = SimpleBar.prototype; _proto.init = function init() { // Save a reference to the instance, so we know this DOM node has already been instancied SimpleBar.instances.set(this.el, this); // We stop here on server-side if (canUseDOM) { this.initDOM(); this.scrollbarWidth = this.getScrollbarWidth(); this.recalculate(); this.initListeners(); } }; _proto.initDOM = function initDOM() { var _this2 = this; var elDocument = getElementDocument(this.el); // make sure this element doesn't have the elements yet if (Array.prototype.filter.call(this.el.children, function (child) { return child.classList.contains(_this2.classNames.wrapper); }).length) { // assume that element has his DOM already initiated this.wrapperEl = this.el.querySelector("." + this.classNames.wrapper); this.contentWrapperEl = this.options.scrollableNode || this.el.querySelector("." + this.classNames.contentWrapper); this.contentEl = this.options.contentNode || this.el.querySelector("." + this.classNames.contentEl); this.offsetEl = this.el.querySelector("." + this.classNames.offset); this.maskEl = this.el.querySelector("." + this.classNames.mask); this.placeholderEl = this.findChild(this.wrapperEl, "." + this.classNames.placeholder); this.heightAutoObserverWrapperEl = this.el.querySelector("." + this.classNames.heightAutoObserverWrapperEl); this.heightAutoObserverEl = this.el.querySelector("." + this.classNames.heightAutoObserverEl); this.axis.x.track.el = this.findChild(this.el, "." + this.classNames.track + "." + this.classNames.horizontal); this.axis.y.track.el = this.findChild(this.el, "." + this.classNames.track + "." + this.classNames.vertical); } else { // Prepare DOM this.wrapperEl = document.createElement('div'); this.contentWrapperEl = document.createElement('div'); this.offsetEl = document.createElement('div'); this.maskEl = document.createElement('div'); this.contentEl = document.createElement('div'); this.placeholderEl = document.createElement('div'); this.heightAutoObserverWrapperEl = document.createElement('div'); this.heightAutoObserverEl = document.createElement('div'); this.wrapperEl.classList.add(this.classNames.wrapper); this.contentWrapperEl.classList.add(this.classNames.contentWrapper); this.offsetEl.classList.add(this.classNames.offset); this.maskEl.classList.add(this.classNames.mask); this.contentEl.classList.add(this.classNames.contentEl); this.placeholderEl.classList.add(this.classNames.placeholder); this.heightAutoObserverWrapperEl.classList.add(this.classNames.heightAutoObserverWrapperEl); this.heightAutoObserverEl.classList.add(this.classNames.heightAutoObserverEl); while (this.el.firstChild) { this.contentEl.appendChild(this.el.firstChild); } this.contentWrapperEl.appendChild(this.contentEl); this.offsetEl.appendChild(this.contentWrapperEl); this.maskEl.appendChild(this.offsetEl); this.heightAutoObserverWrapperEl.appendChild(this.heightAutoObserverEl); this.wrapperEl.appendChild(this.heightAutoObserverWrapperEl); this.wrapperEl.appendChild(this.maskEl); this.wrapperEl.appendChild(this.placeholderEl); this.el.appendChild(this.wrapperEl); } if (!this.axis.x.track.el || !this.axis.y.track.el) { var track = document.createElement('div'); var scrollbar = document.createElement('div'); track.classList.add(this.classNames.track); scrollbar.classList.add(this.classNames.scrollbar); track.appendChild(scrollbar); this.axis.x.track.el = track.cloneNode(true); this.axis.x.track.el.classList.add(this.classNames.horizontal); this.axis.y.track.el = track.cloneNode(true); this.axis.y.track.el.classList.add(this.classNames.vertical); this.el.appendChild(this.axis.x.track.el); this.el.appendChild(this.axis.y.track.el); } this.axis.x.scrollbar.el = this.axis.x.track.el.querySelector("." + this.classNames.scrollbar); this.axis.y.scrollbar.el = this.axis.y.track.el.querySelector("." + this.classNames.scrollbar); if (!this.options.autoHide) { this.axis.x.scrollbar.el.classList.add(this.classNames.visible); this.axis.y.scrollbar.el.classList.add(this.classNames.visible); } this.el.setAttribute('data-simplebar', 'init'); }; _proto.initListeners = function initListeners() { var _this3 = this; var elWindow = getElementWindow(this.el); // Event listeners if (this.options.autoHide) { this.el.addEventListener('mouseenter', this.onMouseEnter); } ['mousedown', 'click', 'dblclick'].forEach(function (e) { _this3.el.addEventListener(e, _this3.onPointerEvent, true); }); ['touchstart', 'touchend', 'touchmove'].forEach(function (e) { _this3.el.addEventListener(e, _this3.onPointerEvent, { capture: true, passive: true }); }); this.el.addEventListener('mousemove', this.onMouseMove); this.el.addEventListener('mouseleave', this.onMouseLeave); this.contentWrapperEl.addEventListener('scroll', this.onScroll); // Browser zoom triggers a window resize elWindow.addEventListener('resize', this.onWindowResize); // Hack for https://github.com/WICG/ResizeObserver/issues/38 var resizeObserverStarted = false; var resizeObserver = elWindow.ResizeObserver || ResizeObserver; this.resizeObserver = new resizeObserver(function () { if (!resizeObserverStarted) return; _this3.recalculate(); }); this.resizeObserver.observe(this.el); this.resizeObserver.observe(this.contentEl); elWindow.requestAnimationFrame(function () { resizeObserverStarted = true; }); // This is required to detect horizontal scroll. Vertical scroll only needs the resizeObserver. this.mutationObserver = new elWindow.MutationObserver(this.recalculate); this.mutationObserver.observe(this.contentEl, { childList: true, subtree: true, characterData: true }); }; _proto.recalculate = function recalculate() { var elWindow = getElementWindow(this.el); this.elStyles = elWindow.getComputedStyle(this.el); this.isRtl = this.elStyles.direction === 'rtl'; var isHeightAuto = this.heightAutoObserverEl.offsetHeight <= 1; var isWidthAuto = this.heightAutoObserverEl.offsetWidth <= 1; var contentElOffsetWidth = this.contentEl.offsetWidth; var contentWrapperElOffsetWidth = this.contentWrapperEl.offsetWidth; var elOverflowX = this.elStyles.overflowX; var elOverflowY = this.elStyles.overflowY; this.contentEl.style.padding = this.elStyles.paddingTop + " " + this.elStyles.paddingRight + " " + this.elStyles.paddingBottom + " " + this.elStyles.paddingLeft; this.wrapperEl.style.margin = "-" + this.elStyles.paddingTop + " -" + this.elStyles.paddingRight + " -" + this.elStyles.paddingBottom + " -" + this.elStyles.paddingLeft; var contentElScrollHeight = this.contentEl.scrollHeight; var contentElScrollWidth = this.contentEl.scrollWidth; this.contentWrapperEl.style.height = isHeightAuto ? 'auto' : '100%'; // Determine placeholder size this.placeholderEl.style.width = isWidthAuto ? contentElOffsetWidth + "px" : 'auto'; this.placeholderEl.style.height = contentElScrollHeight + "px"; var contentWrapperElOffsetHeight = this.contentWrapperEl.offsetHeight; this.axis.x.isOverflowing = contentElScrollWidth > contentElOffsetWidth; this.axis.y.isOverflowing = contentElScrollHeight > contentWrapperElOffsetHeight; // Set isOverflowing to false if user explicitely set hidden overflow this.axis.x.isOverflowing = elOverflowX === 'hidden' ? false : this.axis.x.isOverflowing; this.axis.y.isOverflowing = elOverflowY === 'hidden' ? false : this.axis.y.isOverflowing; this.axis.x.forceVisible = this.options.forceVisible === 'x' || this.options.forceVisible === true; this.axis.y.forceVisible = this.options.forceVisible === 'y' || this.options.forceVisible === true; this.hideNativeScrollbar(); // Set isOverflowing to false if scrollbar is not necessary (content is shorter than offset) var offsetForXScrollbar = this.axis.x.isOverflowing ? this.scrollbarWidth : 0; var offsetForYScrollbar = this.axis.y.isOverflowing ? this.scrollbarWidth : 0; this.axis.x.isOverflowing = this.axis.x.isOverflowing && contentElScrollWidth > contentWrapperElOffsetWidth - offsetForYScrollbar; this.axis.y.isOverflowing = this.axis.y.isOverflowing && contentElScrollHeight > contentWrapperElOffsetHeight - offsetForXScrollbar; this.axis.x.scrollbar.size = this.getScrollbarSize('x'); this.axis.y.scrollbar.size = this.getScrollbarSize('y'); this.axis.x.scrollbar.el.style.width = this.axis.x.scrollbar.size + "px"; this.axis.y.scrollbar.el.style.height = this.axis.y.scrollbar.size + "px"; this.positionScrollbar('x'); this.positionScrollbar('y'); this.toggleTrackVisibility('x'); this.toggleTrackVisibility('y'); } /** * Calculate scrollbar size */ ; _proto.getScrollbarSize = function getScrollbarSize(axis) { if (axis === void 0) { axis = 'y'; } if (!this.axis[axis].isOverflowing) { return 0; } var contentSize = this.contentEl[this.axis[axis].scrollSizeAttr]; var trackSize = this.axis[axis].track.el[this.axis[axis].offsetSizeAttr]; var scrollbarSize; var scrollbarRatio = trackSize / contentSize; // Calculate new height/position of drag handle. scrollbarSize = Math.max(~~(scrollbarRatio * trackSize), this.options.scrollbarMinSize); if (this.options.scrollbarMaxSize) { scrollbarSize = Math.min(scrollbarSize, this.options.scrollbarMaxSize); } return scrollbarSize; }; _proto.positionScrollbar = function positionScrollbar(axis) { if (axis === void 0) { axis = 'y'; } if (!this.axis[axis].isOverflowing) { return; } var contentSize = this.contentWrapperEl[this.axis[axis].scrollSizeAttr]; var trackSize = this.axis[axis].track.el[this.axis[axis].offsetSizeAttr]; var hostSize = parseInt(this.elStyles[this.axis[axis].sizeAttr], 10); var scrollbar = this.axis[axis].scrollbar; var scrollOffset = this.contentWrapperEl[this.axis[axis].scrollOffsetAttr]; scrollOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollOffset : scrollOffset; var scrollPourcent = scrollOffset / (contentSize - hostSize); var handleOffset = ~~((trackSize - scrollbar.size) * scrollPourcent); handleOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? handleOffset + (trackSize - scrollbar.size) : handleOffset; scrollbar.el.style.transform = axis === 'x' ? "translate3d(" + handleOffset + "px, 0, 0)" : "translate3d(0, " + handleOffset + "px, 0)"; }; _proto.toggleTrackVisibility = function toggleTrackVisibility(axis) { if (axis === void 0) { axis = 'y'; } var track = this.axis[axis].track.el; var scrollbar = this.axis[axis].scrollbar.el; if (this.axis[axis].isOverflowing || this.axis[axis].forceVisible) { track.style.visibility = 'visible'; this.contentWrapperEl.style[this.axis[axis].overflowAttr] = 'scroll'; } else { track.style.visibility = 'hidden'; this.contentWrapperEl.style[this.axis[axis].overflowAttr] = 'hidden'; } // Even if forceVisible is enabled, scrollbar itself should be hidden if (this.axis[axis].isOverflowing) { scrollbar.style.display = 'block'; } else { scrollbar.style.display = 'none'; } }; _proto.hideNativeScrollbar = function hideNativeScrollbar() { this.offsetEl.style[this.isRtl ? 'left' : 'right'] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "-" + this.scrollbarWidth + "px" : 0; this.offsetEl.style.bottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "-" + this.scrollbarWidth + "px" : 0; } /** * On scroll event handling */ ; _proto.onMouseMoveForAxis = function onMouseMoveForAxis(axis) { if (axis === void 0) { axis = 'y'; } this.axis[axis].track.rect = this.axis[axis].track.el.getBoundingClientRect(); this.axis[axis].scrollbar.rect = this.axis[axis].scrollbar.el.getBoundingClientRect(); var isWithinScrollbarBoundsX = this.isWithinBounds(this.axis[axis].scrollbar.rect); if (isWithinScrollbarBoundsX) { this.axis[axis].scrollbar.el.classList.add(this.classNames.hover); } else { this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover); } if (this.isWithinBounds(this.axis[axis].track.rect)) { this.showScrollbar(axis); this.axis[axis].track.el.classList.add(this.classNames.hover); } else { this.axis[axis].track.el.classList.remove(this.classNames.hover); } }; _proto.onMouseLeaveForAxis = function onMouseLeaveForAxis(axis) { if (axis === void 0) { axis = 'y'; } this.axis[axis].track.el.classList.remove(this.classNames.hover); this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover); }; /** * Show scrollbar */ _proto.showScrollbar = function showScrollbar(axis) { if (axis === void 0) { axis = 'y'; } var scrollbar = this.axis[axis].scrollbar.el; if (!this.axis[axis].isVisible) { scrollbar.classList.add(this.classNames.visible); this.axis[axis].isVisible = true; } if (this.options.autoHide) { this.hideScrollbars(); } } /** * Hide Scrollbar */ ; /** * on scrollbar handle drag movement starts */ _proto.onDragStart = function onDragStart(e, axis) { if (axis === void 0) { axis = 'y'; } var elDocument = getElementDocument(this.el); var elWindow = getElementWindow(this.el); var scrollbar = this.axis[axis].scrollbar; // Measure how far the user's mouse is from the top of the scrollbar drag handle. var eventOffset = axis === 'y' ? e.pageY : e.pageX; this.axis[axis].dragOffset = eventOffset - scrollbar.rect[this.axis[axis].offsetAttr]; this.draggedAxis = axis; this.el.classList.add(this.classNames.dragging); elDocument.addEventListener('mousemove', this.drag, true); elDocument.addEventListener('mouseup', this.onEndDrag, true); if (this.removePreventClickId === null) { elDocument.addEventListener('click', this.preventClick, true); elDocument.addEventListener('dblclick', this.preventClick, true); } else { elWindow.clearTimeout(this.removePreventClickId); this.removePreventClickId = null; } } /** * Drag scrollbar handle */ ; _proto.onTrackClick = function onTrackClick(e, axis) { var _this4 = this; if (axis === void 0) { axis = 'y'; } if (!this.options.clickOnTrack) return; var elWindow = getElementWindow(this.el); this.axis[axis].scrollbar.rect = this.axis[axis].scrollbar.el.getBoundingClientRect(); var scrollbar = this.axis[axis].scrollbar; var scrollbarOffset = scrollbar.rect[this.axis[axis].offsetAttr]; var hostSize = parseInt(this.elStyles[this.axis[axis].sizeAttr], 10); var scrolled = this.contentWrapperEl[this.axis[axis].scrollOffsetAttr]; var t = axis === 'y' ? this.mouseY - scrollbarOffset : this.mouseX - scrollbarOffset; var dir = t < 0 ? -1 : 1; var scrollSize = dir === -1 ? scrolled - hostSize : scrolled + hostSize; var speed = 40; var scrollTo = function scrollTo() { if (dir === -1) { if (scrolled > scrollSize) { var _this4$contentWrapper; scrolled -= speed; _this4.contentWrapperEl.scrollTo((_this4$contentWrapper = {}, _this4$contentWrapper[_this4.axis[axis].offsetAttr] = scrolled, _this4$contentWrapper)); elWindow.requestAnimationFrame(scrollTo); } } else { if (scrolled < scrollSize) { var _this4$contentWrapper2; scrolled += speed; _this4.contentWrapperEl.scrollTo((_this4$contentWrapper2 = {}, _this4$contentWrapper2[_this4.axis[axis].offsetAttr] = scrolled, _this4$contentWrapper2)); elWindow.requestAnimationFrame(scrollTo); } } }; scrollTo(); } /** * Getter for content element */ ; _proto.getContentElement = function getContentElement() { return this.contentEl; } /** * Getter for original scrolling element */ ; _proto.getScrollElement = function getScrollElement() { return this.contentWrapperEl; }; _proto.getScrollbarWidth = function getScrollbarWidth() { // Try/catch for FF 56 throwing on undefined computedStyles try { // Detect browsers supporting CSS scrollbar styling and do not calculate if (getComputedStyle(this.contentWrapperEl, '::-webkit-scrollbar').display === 'none' || 'scrollbarWidth' in document.documentElement.style || '-ms-overflow-style' in document.documentElement.style) { return 0; } else { return scrollbarWidth(); } } catch (e) { return scrollbarWidth(); } }; _proto.removeListeners = function removeListeners() { var _this5 = this; var elWindow = getElementWindow(this.el); // Event listeners if (this.options.autoHide) { this.el.removeEventListener('mouseenter', this.onMouseEnter); } ['mousedown', 'click', 'dblclick'].forEach(function (e) { _this5.el.removeEventListener(e, _this5.onPointerEvent, true); }); ['touchstart', 'touchend', 'touchmove'].forEach(function (e) { _this5.el.removeEventListener(e, _this5.onPointerEvent, { capture: true, passive: true }); }); this.el.removeEventListener('mousemove', this.onMouseMove); this.el.removeEventListener('mouseleave', this.onMouseLeave); this.contentWrapperEl.removeEventListener('scroll', this.onScroll); elWindow.removeEventListener('resize', this.onWindowResize); this.mutationObserver.disconnect(); this.resizeObserver.disconnect(); // Cancel all debounced functions this.recalculate.cancel(); this.onMouseMove.cancel(); this.hideScrollbars.cancel(); this.onWindowResize.cancel(); } /** * UnMount mutation observer and delete SimpleBar instance from DOM element */ ; _proto.unMount = function unMount() { this.removeListeners(); SimpleBar.instances.delete(this.el); } /** * Check if mouse is within bounds */ ; _proto.isWithinBounds = function isWithinBounds(bbox) { return this.mouseX >= bbox.left && this.mouseX <= bbox.left + bbox.width && this.mouseY >= bbox.top && this.mouseY <= bbox.top + bbox.height; } /** * Find element children matches query */ ; _proto.findChild = function findChild(el, query) { var matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector; return Array.prototype.filter.call(el.children, function (child) { return matches.call(child, query); })[0]; }; return SimpleBar; }(); SimpleBar.defaultOptions = { autoHide: true, forceVisible: false, clickOnTrack: true, classNames: { contentEl: 'simplebar-content', contentWrapper: 'simplebar-content-wrapper', offset: 'simplebar-offset', mask: 'simplebar-mask', wrapper: 'simplebar-wrapper', placeholder: 'simplebar-placeholder', scrollbar: 'simplebar-scrollbar', track: 'simplebar-track', heightAutoObserverWrapperEl: 'simplebar-height-auto-observer-wrapper', heightAutoObserverEl: 'simplebar-height-auto-observer', visible: 'simplebar-visible', horizontal: 'simplebar-horizontal', vertical: 'simplebar-vertical', hover: 'simplebar-hover', dragging: 'simplebar-dragging' }, scrollbarMinSize: 25, scrollbarMaxSize: 0, timeout: 1000 }; SimpleBar.instances = new WeakMap(); SimpleBar.initDOMLoadedElements = function () { document.removeEventListener('DOMContentLoaded', this.initDOMLoadedElements); window.removeEventListener('load', this.initDOMLoadedElements); Array.prototype.forEach.call(document.querySelectorAll('[data-simplebar]:not([data-simplebar="init"])'), function (el) { if (!SimpleBar.instances.has(el)) new SimpleBar(el, getOptions(el.attributes)); }); }; SimpleBar.removeObserver = function () { this.globalObserver.disconnect(); }; SimpleBar.initHtmlApi = function () { this.initDOMLoadedElements = this.initDOMLoadedElements.bind(this); // MutationObserver is IE11+ if (typeof MutationObserver !== 'undefined') { // Mutation observer to observe dynamically added elements this.globalObserver = new MutationObserver(SimpleBar.handleMutations); this.globalObserver.observe(document, { childList: true, subtree: true }); } // Taken from jQuery `ready` function // Instantiate elements already present on the page if (document.readyState === 'complete' || document.readyState !== 'loading' && !document.documentElement.doScroll) { // Handle it asynchronously to allow scripts the opportunity to delay init window.setTimeout(this.initDOMLoadedElements); } else { document.addEventListener('DOMContentLoaded', this.initDOMLoadedElements); window.addEventListener('load', this.initDOMLoadedElements); } }; SimpleBar.handleMutations = function (mutations) { mutations.forEach(function (mutation) { Array.prototype.forEach.call(mutation.addedNodes, function (addedNode) { if (addedNode.nodeType === 1) { if (addedNode.hasAttribute('data-simplebar')) { !SimpleBar.instances.has(addedNode) && new SimpleBar(addedNode, getOptions(addedNode.attributes)); } else { Array.prototype.forEach.call(addedNode.querySelectorAll('[data-simplebar]:not([data-simplebar="init"])'), function (el) { !SimpleBar.instances.has(el) && new SimpleBar(el, getOptions(el.attributes)); }); } } }); Array.prototype.forEach.call(mutation.removedNodes, function (removedNode) { if (removedNode.nodeType === 1) { if (removedNode.hasAttribute('[data-simplebar="init"]')) { SimpleBar.instances.has(removedNode) && SimpleBar.instances.get(removedNode).unMount(); } else { Array.prototype.forEach.call(removedNode.querySelectorAll('[data-simplebar="init"]'), function (el) { SimpleBar.instances.has(el) && SimpleBar.instances.get(el).unMount(); }); } } }); }); }; SimpleBar.getOptions = getOptions; /** * HTML API * Called only in a browser env. */ if (canUseDOM) { SimpleBar.initHtmlApi(); } export default SimpleBar; //# sourceMappingURL=simplebar.esm.js.map