diff --git a/src/components/carousel/carousel.js b/src/components/carousel/carousel.js index d661a115b3d..c3d594b116f 100644 --- a/src/components/carousel/carousel.js +++ b/src/components/carousel/carousel.js @@ -1,5 +1,6 @@ import observeDom from '../../utils/observe-dom' import KeyCodes from '../../utils/key-codes' +import noop from '../../utils/noop' import { selectAll, reflow, @@ -28,7 +29,7 @@ const DIRECTION = { const TRANS_DURATION = 600 + 50 // Time for mouse compat events to fire after touch -const TOUCHEVENT_COMPAT_WAIT = 500 +const TOUCH_EVENT_COMPAT_WAIT = 500 // Number of pixels to consider touch move a swipe const SWIPE_THRESHOLD = 40 @@ -50,7 +51,7 @@ const TransitionEndEvents = { const EventOptions = { passive: true, capture: false } // Return the browser specific transitionEnd event name -function getTransisionEndEvent(el) { +function getTransitionEndEvent(el) { for (const name in TransitionEndEvents) { if (el.style[name] !== undefined) { return TransitionEndEvents[name] @@ -61,8 +62,6 @@ function getTransisionEndEvent(el) { return null } -const noop = () => {} - // @vue/component export default { name: 'BCarousel', @@ -194,7 +193,7 @@ export default { }, mounted() { // Cache current browser transitionend event name - this.transitionEndEvent = getTransisionEndEvent(this.$el) || null + this.transitionEndEvent = getTransitionEndEvent(this.$el) || null // Get all slides this.updateSlides() // Observe child changes so we can update slide list @@ -205,7 +204,7 @@ export default { attributeFilter: ['id'] }) }, - beforeDestroy() /* istanbul ignore next: dificult to test */ { + beforeDestroy() /* istanbul ignore next: difficult to test */ { clearTimeout(this._animationTimeout) clearTimeout(this._touchTimeout) clearInterval(this._intervalId) @@ -217,7 +216,7 @@ export default { // Set slide setSlide(slide, direction = null) { // Don't animate when page is not visible - /* istanbul ignore if: dificult to test */ + /* istanbul ignore if: difficult to test */ if (inBrowser && document.visibilityState && document.hidden) { return } @@ -261,7 +260,7 @@ export default { if (!evt) { this.isPaused = false } - /* istanbul ignore next: most likley will never happen, but just in case */ + /* istanbul ignore next: most likely will never happen, but just in case */ if (this._intervalId) { clearInterval(this._intervalId) this._intervalId = null @@ -271,9 +270,9 @@ export default { this._intervalId = setInterval(this.next, Math.max(1000, this.interval)) } }, - // Re-Start auto rotate slides when focus/hover leaves the carousel + // Restart auto rotate slides when focus/hover leaves the carousel restart(evt) { - /* istanbul ignore if: dificult to test */ + /* istanbul ignore if: difficult to test */ if (!this.$el.contains(document.activeElement)) { this.start() } @@ -314,7 +313,7 @@ export default { addClass(nextSlide, dirClass) // Transition End handler let called = false - /* istanbul ignore next: dificult to test */ + /* istanbul ignore next: difficult to test */ const onceTransEnd = evt => { if (called) { return @@ -347,7 +346,7 @@ export default { const events = this.transitionEndEvent.split(/\s+/) events.forEach(event => eventOn(currentSlide, event, onceTransEnd, EventOptions)) } - // Fallback to setTimeout + // Fallback to setTimeout() this._animationTimeout = setTimeout(onceTransEnd, TRANS_DURATION) } if (isCycling) { @@ -393,16 +392,16 @@ export default { } }, handleSwipe() /* istanbul ignore next: JSDOM doesn't support touch events */ { - const absDeltax = Math.abs(this.touchDeltaX) - if (absDeltax <= SWIPE_THRESHOLD) { + const absDeltaX = Math.abs(this.touchDeltaX) + if (absDeltaX <= SWIPE_THRESHOLD) { return } - const direction = absDeltax / this.touchDeltaX + const direction = absDeltaX / this.touchDeltaX if (direction > 0) { - // swipe left + // Swipe left this.prev() } else if (direction < 0) { - // swipe right + // Swipe right this.next() } }, @@ -414,7 +413,7 @@ export default { } }, touchMove(evt) /* istanbul ignore next: JSDOM doesn't support touch events */ { - // ensure swiping with one touch and not pinching + // Ensure swiping with one touch and not pinching if (evt.touches && evt.touches.length > 1) { this.touchDeltaX = 0 } else { @@ -439,7 +438,7 @@ export default { } this._touchTimeout = setTimeout( this.start, - TOUCHEVENT_COMPAT_WAIT + Math.max(1000, this.interval) + TOUCH_EVENT_COMPAT_WAIT + Math.max(1000, this.interval) ) } }, @@ -458,7 +457,7 @@ export default { [this.$slots.default] ) - // Prev and Next Controls + // Prev and next controls let controls = h(false) if (this.controls) { controls = [ @@ -567,7 +566,8 @@ export default { } // Touch support event handlers for environment if (!this.noTouch && hasTouchSupport) { - /* istanbul ignore next: JSDOM doesn't support touch events */ // Attach appropriate listeners (passsive mode) + // Attach appropriate listeners (passive mode) + /* istanbul ignore next: JSDOM doesn't support touch events */ if (hasPointerEvent) { on['&pointerdown'] = this.touchStart on['&pointerup'] = this.touchEnd diff --git a/src/utils/noop.js b/src/utils/noop.js new file mode 100644 index 00000000000..9b98d9cfac1 --- /dev/null +++ b/src/utils/noop.js @@ -0,0 +1,3 @@ +const noop = () => {} + +export default noop diff --git a/src/utils/tooltip.class.js b/src/utils/tooltip.class.js index 580e921638a..36358963689 100644 --- a/src/utils/tooltip.class.js +++ b/src/utils/tooltip.class.js @@ -1,5 +1,6 @@ import Popper from 'popper.js' import BvEvent from './bv-event.class' +import noop from './noop' import { from as arrayFrom } from './array' import { closest, @@ -25,7 +26,7 @@ const TRANSITION_DURATION = 150 // Modal $root hidden event const MODAL_CLOSE_EVENT = 'bv::modal::hidden' -// Modal container for appending tip/popover +// Modal container for appending tooltip/popover const MODAL_CLASS = '.modal-content' const AttachmentMap = { @@ -76,15 +77,6 @@ const Selector = { ARROW: '.arrow' } -// ESLINT: Not used -// const Trigger = { -// HOVER: 'hover', -// FOCUS: 'focus', -// CLICK: 'click', -// BLUR: 'blur', -// MANUAL: 'manual' -// } - const Defaults = { animation: true, template: @@ -105,7 +97,7 @@ const Defaults = { boundary: 'scrollParent' } -// Transition Event names +// Transition event names const TransitionEndEvents = { WebkitTransition: ['webkitTransitionEnd'], MozTransition: ['transitionend'], @@ -113,15 +105,14 @@ const TransitionEndEvents = { transition: ['transitionend'] } -// Client Side Tip ID counter for aria-describedby attribute -// Could use Alex's uid generator util +// Client-side tip ID counter for aria-describedby attribute // Each tooltip requires a unique client side ID let NEXTID = 1 /* istanbul ignore next */ const generateId = name => `__BV_${name}_${NEXTID++}__` /* - * ToolTip Class definition + * ToolTip class definition */ /* istanbul ignore next: difficult to test in Jest/JSDOM environment */ class ToolTip { @@ -147,6 +138,7 @@ class ToolTip { this.$doShow = this.doShow.bind(this) this.$doDisable = this.doDisable.bind(this) this.$doEnable = this.doEnable.bind(this) + this._noop = noop.bind(this) // Set the configuration this.updateConfig(config) } @@ -284,7 +276,7 @@ class ToolTip { this.fixTitle() this.setContent(tip) if (!this.isWithContent(tip)) { - // if No content, don't bother showing + // If no content, don't bother showing this.$tip = null return } @@ -327,7 +319,7 @@ class ToolTip { this.removePopper() this.$popper = new Popper(this.$element, tip, this.getPopperConfig(placement, tip)) - // Transitionend Callback + // Transitionend callback const complete = () => { if (this.$config.animation) { this.fixTransition(tip) @@ -356,7 +348,7 @@ class ToolTip { this.transitionOnce(tip, complete) } - // handler for periodic visibility check + // Handler for periodic visibility check visibleCheck(on) { clearInterval(this.$visibleInterval) this.$visibleInterval = null @@ -382,14 +374,14 @@ class ToolTip { // On-touch start listeners this.setOnTouchStartListener(on) if (on && /(focus|blur)/.test(this.$config.trigger)) { - // If focus moves between trigger element and tip container, dont close + // If focus moves between trigger element and tip container, don't close eventOn(this.$tip, 'focusout', this) } else { eventOff(this.$tip, 'focusout', this) } } - // force hide of tip (internal method) + // Force hide of tip (internal method) forceHide() { if (!this.$tip || !hasClass(this.$tip, ClassName.SHOW)) { return @@ -424,11 +416,11 @@ class ToolTip { return } - // Transitionend Callback + // Transitionend callback /* istanbul ignore next */ const complete = () => { if (this.$hoverState !== HoverState.SHOW && tip.parentNode) { - // Remove tip from dom, and force recompile on next show + // Remove tip from DOM, and force recompile on next show tip.parentNode.removeChild(tip) this.removeAriaDescribedby() this.removePopper() @@ -481,13 +473,14 @@ class ToolTip { getContainer() { const container = this.$config.container const body = document.body - // If we are in a modal, we append to the modal instead of body, unless a container is specified + // If we are in a modal, we append to the modal instead of body, + // unless a container is specified return container === false ? closest(MODAL_CLASS, this.$element) || body : select(container, body) || body } - // Will be overridden by popover if needed + // Will be overridden by PopOver if needed addAriaDescribedby() { // Add aria-describedby on trigger element, without removing any other IDs let desc = getAttr(this.$element, 'aria-describedby') || '' @@ -499,7 +492,7 @@ class ToolTip { setAttr(this.$element, 'aria-describedby', desc) } - // Will be overridden by popover if needed + // Will be overridden by PopOver if needed removeAriaDescribedby() { let desc = getAttr(this.$element, 'aria-describedby') || '' desc = desc @@ -544,7 +537,7 @@ class ToolTip { transEvents.forEach(evtName => { eventOn(tip, evtName, fnOnce) }) - // Fallback to setTimeout + // Fallback to setTimeout() this.$fadeTimeout = setTimeout(fnOnce, TRANSITION_DURATION) } else { fnOnce() @@ -620,7 +613,7 @@ class ToolTip { } const allowHtml = this.$config.html if (typeof content === 'object' && content.nodeType) { - // content is a DOM node + // Content is a DOM node if (allowHtml) { if (content.parentElement !== container) { container.innerHTML = '' @@ -643,7 +636,8 @@ class ToolTip { title = title(this.$element) } if (typeof title === 'object' && title.nodeType && !title.innerHTML.trim()) { - // We have a DOM node, but without inner content, so just return empty string + // We have a DOM node, but without inner content, + // so just return empty string title = '' } if (typeof title === 'string') { @@ -669,8 +663,8 @@ class ToolTip { // Listen for global show/hide events this.setRootListener(true) - // Using 'this' as the handler will get automatically directed to this.handleEvent - // And maintain our binding to 'this' + // Using 'this' as the handler will get automatically directed to + // this.handleEvent and maintain our binding to 'this' triggers.forEach(trigger => { if (trigger === 'click') { eventOn(el, 'click', this) @@ -701,7 +695,7 @@ class ToolTip { handleEvent(e) { // This special method allows us to use "this" as the event handlers if (isDisabled(this.$element)) { - // If disabled, don't do anything. Note: if tip is shown before element gets + // If disabled, don't do anything. Note: If tip is shown before element gets // disabled, then tip not close until no longer disabled or forcefully closed. return } @@ -720,7 +714,7 @@ class ToolTip { this.enter(e) } else if (type === 'focusout') { // target is the element which is loosing focus - // And relatedTarget is the element gaining focus + // and relatedTarget is the element gaining focus if ($tip && $element && $element.contains(target) && $tip.contains(relatedTarget)) { // If focus moves from $element to $tip, don't trigger a leave return @@ -759,7 +753,7 @@ class ToolTip { } } else { if (this.$routeWatcher) { - // cancel the route watcher by calling the stored reference + // Cancel the route watcher by calling the stored reference this.$routeWatcher() this.$routeWatcher = null } @@ -836,9 +830,9 @@ class ToolTip { /* istanbul ignore next */ setOnTouchStartListener(on) { - // if this is a touch-enabled device we add extra - // empty mouseover listeners to the body's immediate children; - // only needed because of broken event delegation on iOS + // If this is a touch-enabled device we add extra + // empty mouseover listeners to the body's immediate children + // Only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html if ('ontouchstart' in document.documentElement) { arrayFrom(document.body.children).forEach(el => { @@ -851,11 +845,6 @@ class ToolTip { } } - /* istanbul ignore next */ - _noop() { - // Empty noop handler for ontouchstart devices - } - fixTitle() { const el = this.$element const titleType = typeof getAttr(el, 'data-original-title')