diff --git a/.eslintrc.js b/.eslintrc.js index 0222428eadc..8116ec010d8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -14,6 +14,14 @@ module.exports = { Vue: true }, rules: { + 'no-unused-vars': [ + 'error', + { + vars: 'all', + args: 'after-used', + ignoreRestSiblings: false + } + ], 'spaced-comment': 'off', // needed to ignore `/*#__PURE__*/` comments 'vue/html-self-closing': [ 'error', diff --git a/docs/common-props.json b/docs/common-props.json index ea442f7f909..4c3bca079c0 100644 --- a/docs/common-props.json +++ b/docs/common-props.json @@ -126,7 +126,7 @@ "description": "Sets the 'placeholder' attribute value on the form control" }, "readonly": { - "description": "Sets the 'readonly' attribute on hte form control" + "description": "Sets the 'readonly' attribute on the form control" }, "plaintext": { "description": "Set the form control as readonly and renders the control to look like plain text (no borders)" diff --git a/docs/markdown/reference/images/README.md b/docs/markdown/reference/images/README.md index 8f6f20f499c..3abf0fd0e0c 100644 --- a/docs/markdown/reference/images/README.md +++ b/docs/markdown/reference/images/README.md @@ -97,7 +97,7 @@ In your `nuxt.config.js` file, add the following to your build section: ```js module.exports = { build: { - extend(config, ctx) { + extend(config) { const vueLoader = config.module.rules.find(rule => rule.loader === 'vue-loader') vueLoader.options.transformAssetUrls = { video: ['src', 'poster'], diff --git a/docs/nuxt.config.js b/docs/nuxt.config.js index 471f99dc4d7..fc961193a4b 100644 --- a/docs/nuxt.config.js +++ b/docs/nuxt.config.js @@ -99,7 +99,7 @@ renderer.blockquote = function(text) { // Bootstrap v4 table support for markdown renderer const originalTable = renderer.table -renderer.table = function(header, body) { +renderer.table = function() { let table = originalTable.apply(this, arguments) table = table .replace('', '
') diff --git a/docs/pages/play.vue b/docs/pages/play.vue index a1fd369b7c5..444d245b59b 100644 --- a/docs/pages/play.vue +++ b/docs/pages/play.vue @@ -597,7 +597,7 @@ export default { // appData watcher this.contentUnWatch = this.$watch( 'appData', - (newVal, oldVal) => { + () => { this.run() }, { deep: true } @@ -605,7 +605,7 @@ export default { // Javascript watcher this.jsUnWatch = this.$watch( () => this.js.trim(), - (newVal, oldVal) => { + () => { this.compileJs() }, { immediate: true } diff --git a/docs/plugins/play.js b/docs/plugins/play.js index 3e4bbf32a95..ced385c6bb0 100644 --- a/docs/plugins/play.js +++ b/docs/plugins/play.js @@ -86,7 +86,7 @@ const destroyVM = (name, vm) => { ;[...document.querySelectorAll(`.vue-example-${name}`)].forEach(removeNode) } -const processExamples = (el, binding, vnode, oldVnode) => { +const processExamples = (el, binding, vnode) => { if (vnode.context.$options.beforeDestroy) { vnode.context.$options.beforeDestroy = [] .concat(vnode.context.$options.beforeDestroy) diff --git a/docs/utils/index.js b/docs/utils/index.js index 5bd63e83a3c..2813b077852 100644 --- a/docs/utils/index.js +++ b/docs/utils/index.js @@ -113,7 +113,7 @@ export const makeTOC = (readme, meta = null) => { // Filter out un-matched values .filter(v => Array.isArray(v)) // Create TOC structure - .forEach(([value, tag, id, content]) => { + .forEach(([, tag, id, content]) => { const href = `#${stripQuotes(id)}` const label = stripHTML(content) if (tag === 'h2') { diff --git a/nuxt/index.js b/nuxt/index.js index 875dd02cf3a..60a99fa4007 100644 --- a/nuxt/index.js +++ b/nuxt/index.js @@ -92,7 +92,7 @@ module.exports = function nuxtBootstrapVue(moduleOptions = {}) { if (!usePretranspiled) { // Use bootstrap-vue source code for smaller prod builds // by aliasing 'bootstrap-vue' to the source files - this.extendBuild((config, { isServer }) => { + this.extendBuild(config => { if (!config.resolve.alias) { config.resolve.alias = {} } diff --git a/scripts/postcss.config.js b/scripts/postcss.config.js index 07054a6ff80..fb139c97fca 100644 --- a/scripts/postcss.config.js +++ b/scripts/postcss.config.js @@ -1,4 +1,4 @@ -module.exports = ctx => ({ +module.exports = () => ({ map: { inline: false, annotation: true, diff --git a/src/components/button-toolbar/button-toolbar.js b/src/components/button-toolbar/button-toolbar.js index a56f591b4dc..77be692fa2d 100644 --- a/src/components/button-toolbar/button-toolbar.js +++ b/src/components/button-toolbar/button-toolbar.js @@ -61,7 +61,7 @@ export const BButtonToolbar = /*#__PURE__*/ Vue.extend({ setItemFocus(item) { item && item.focus && item.focus() }, - focusFirst(evt) { + focusFirst() { const items = this.getItems() this.setItemFocus(items[0]) }, @@ -81,7 +81,7 @@ export const BButtonToolbar = /*#__PURE__*/ Vue.extend({ this.setItemFocus(items[0]) } }, - focusLast(evt) { + focusLast() { const items = this.getItems().reverse() this.setItemFocus(items[0]) }, diff --git a/src/components/button-toolbar/button-toolbar.spec.js b/src/components/button-toolbar/button-toolbar.spec.js index c3806f8da6e..15f0fd0c0df 100644 --- a/src/components/button-toolbar/button-toolbar.spec.js +++ b/src/components/button-toolbar/button-toolbar.spec.js @@ -85,12 +85,9 @@ describe('button-toolbar', () => { const App = Vue.extend({ render(h) { return h(BButtonToolbar, { props: { keyNav: true } }, [ - h(BButtonGroup, {}, [h(BButton, {}, 'a'), h(BButton, {}, 'b')]), - h(BButtonGroup, {}, [ - h(BButton, { props: { disabled: true } }, 'c'), - h(BButton, {}, 'd') - ]), - h(BButtonGroup, {}, [h(BButton, {}, 'e'), h(BButton, {}, 'f')]) + h(BButtonGroup, [h(BButton, 'a'), h(BButton, 'b')]), + h(BButtonGroup, [h(BButton, { props: { disabled: true } }, 'c'), h(BButton, 'd')]), + h(BButtonGroup, [h(BButton, 'e'), h(BButton, 'f')]) ]) } }) diff --git a/src/components/button/button-close.js b/src/components/button/button-close.js index 5b749ef4008..2c16d7300f7 100644 --- a/src/components/button/button-close.js +++ b/src/components/button/button-close.js @@ -30,7 +30,7 @@ export const BButtonClose = /*#__PURE__*/ Vue.extend({ name: NAME, functional: true, props, - render(h, { props, data, listeners, slots, scopedSlots }) { + render(h, { props, data, slots, scopedSlots }) { const $slots = slots() const $scopedSlots = scopedSlots || {} diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 681bc002519..9fff0139ce9 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -208,7 +208,7 @@ describe('button', () => { disabled: true }, listeners: { - click: e => { + click: () => { called++ } } diff --git a/src/components/carousel/carousel.js b/src/components/carousel/carousel.js index 12de4a25ed4..db382fdac7d 100644 --- a/src/components/carousel/carousel.js +++ b/src/components/carousel/carousel.js @@ -3,16 +3,9 @@ import KeyCodes from '../../utils/key-codes' import noop from '../../utils/noop' import observeDom from '../../utils/observe-dom' import { getComponentConfig } from '../../utils/config' -import { - selectAll, - reflow, - addClass, - removeClass, - setAttr, - eventOn, - eventOff -} from '../../utils/dom' +import { selectAll, reflow, addClass, removeClass, setAttr } from '../../utils/dom' import { isBrowser, hasTouchSupport, hasPointerEventSupport } from '../../utils/env' +import { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff } from '../../utils/events' import { isUndefined } from '../../utils/inspect' import { toInteger } from '../../utils/number' import idMixin from '../../mixins/id' @@ -55,8 +48,6 @@ const TransitionEndEvents = { transition: 'transitionend' } -const EventOptions = { passive: true, capture: false } - // Return the browser specific transitionEnd event name const getTransitionEndEvent = el => { for (const name in TransitionEndEvents) { @@ -308,7 +299,7 @@ export const BCarousel = /*#__PURE__*/ Vue.extend({ } }, // Restart auto rotate slides when focus/hover leaves the carousel - restart(evt) /* istanbul ignore next: difficult to test */ { + restart() /* istanbul ignore next: difficult to test */ { if (!this.$el.contains(document.activeElement)) { this.start() } @@ -350,7 +341,7 @@ export const BCarousel = /*#__PURE__*/ Vue.extend({ // Transition End handler let called = false /* istanbul ignore next: difficult to test */ - const onceTransEnd = evt => { + const onceTransEnd = () => { if (called) { return } @@ -358,7 +349,9 @@ export const BCarousel = /*#__PURE__*/ Vue.extend({ /* istanbul ignore if: transition events cant be tested in JSDOM */ if (this.transitionEndEvent) { const events = this.transitionEndEvent.split(/\s+/) - events.forEach(evt => eventOff(currentSlide, evt, onceTransEnd, EventOptions)) + events.forEach(evt => + eventOff(currentSlide, evt, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE) + ) } this._animationTimeout = null removeClass(nextSlide, dirClass) @@ -380,7 +373,9 @@ export const BCarousel = /*#__PURE__*/ Vue.extend({ /* istanbul ignore if: transition events cant be tested in JSDOM */ if (this.transitionEndEvent) { const events = this.transitionEndEvent.split(/\s+/) - events.forEach(event => eventOn(currentSlide, event, onceTransEnd, EventOptions)) + events.forEach(event => + eventOn(currentSlide, event, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE) + ) } // Fallback to setTimeout() this._animationTimeout = setTimeout(onceTransEnd, TRANS_DURATION) diff --git a/src/components/carousel/carousel.spec.js b/src/components/carousel/carousel.spec.js index 6fc89d0cea5..9784a01e609 100644 --- a/src/components/carousel/carousel.spec.js +++ b/src/components/carousel/carousel.spec.js @@ -32,10 +32,10 @@ const appDef = { } }, [ - h(BCarouselSlide, {}, 'slide 1'), - h(BCarouselSlide, {}, 'slide 2'), - h(BCarouselSlide, {}, 'slide 3'), - h(BCarouselSlide, {}, 'slide 4') + h(BCarouselSlide, 'slide 1'), + h(BCarouselSlide, 'slide 2'), + h(BCarouselSlide, 'slide 3'), + h(BCarouselSlide, 'slide 4') ] ) } diff --git a/src/components/carousel/package.json b/src/components/carousel/package.json index 1f5a5fc3fc0..61999b20068 100644 --- a/src/components/carousel/package.json +++ b/src/components/carousel/package.json @@ -36,7 +36,7 @@ }, { "prop": "noHoverPause", - "description": "When set, disables the pausing of hte slide show when the current slide is hovered" + "description": "When set, disables the pausing of the slide show when the current slide is hovered" }, { "prop": "interval", diff --git a/src/components/collapse/collapse.js b/src/components/collapse/collapse.js index 50728b886b9..7ad53694992 100644 --- a/src/components/collapse/collapse.js +++ b/src/components/collapse/collapse.js @@ -1,19 +1,11 @@ import Vue from '../../utils/vue' +import { isBrowser } from '../../utils/env' +import { addClass, hasClass, removeClass, closest, matches, getCS } from '../../utils/dom' +import { EVENT_OPTIONS_NO_CAPTURE, eventOnOff } from '../../utils/events' +import { BVCollapse } from '../../utils/bv-collapse' import idMixin from '../../mixins/id' import listenOnRootMixin from '../../mixins/listen-on-root' import normalizeSlotMixin from '../../mixins/normalize-slot' -import { isBrowser } from '../../utils/env' -import { BVCollapse } from '../../utils/bv-collapse' -import { - addClass, - hasClass, - removeClass, - closest, - matches, - getCS, - eventOn, - eventOff -} from '../../utils/dom' // Events we emit on $root const EVENT_STATE = 'bv::collapse::state' @@ -26,9 +18,6 @@ const EVENT_STATE_SYNC = 'bv::collapse::sync::state' const EVENT_TOGGLE = 'bv::toggle::collapse' const EVENT_STATE_REQUEST = 'bv::request::collapse::state' -// Event listener options -const EventOptions = { passive: true, capture: false } - // @vue/component export const BCollapse = /*#__PURE__*/ Vue.extend({ name: 'BCollapse', @@ -137,28 +126,27 @@ export const BCollapse = /*#__PURE__*/ Vue.extend({ }, methods: { setWindowEvents(on) { - const method = on ? eventOn : eventOff - method(window, 'resize', this.handleResize, EventOptions) - method(window, 'orientationchange', this.handleResize, EventOptions) + eventOnOff(on, window, 'resize', this.handleResize, EVENT_OPTIONS_NO_CAPTURE) + eventOnOff(on, window, 'orientationchange', this.handleResize, EVENT_OPTIONS_NO_CAPTURE) }, toggle() { this.show = !this.show }, - onEnter(el) { + onEnter() { this.transitioning = true // This should be moved out so we can add cancellable events this.$emit('show') }, - onAfterEnter(el) { + onAfterEnter() { this.transitioning = false this.$emit('shown') }, - onLeave(el) { + onLeave() { this.transitioning = true // This should be moved out so we can add cancellable events this.$emit('hide') }, - onAfterLeave(el) { + onAfterLeave() { this.transitioning = false this.$emit('hidden') }, diff --git a/src/components/collapse/collapse.spec.js b/src/components/collapse/collapse.spec.js index ce544fa3c2c..a8872a4956f 100644 --- a/src/components/collapse/collapse.spec.js +++ b/src/components/collapse/collapse.spec.js @@ -411,7 +411,7 @@ describe('collapse', () => { const localVue = CreateLocalVue() const App = localVue.extend({ render(h) { - return h('div', {}, [ + return h('div', [ // JSDOM supports getComputedStyle when using stylesheets (non responsive) // https://github.com/jsdom/jsdom/blob/master/Changelog.md#030 h('style', { attrs: { type: 'text/css' } }, '.collapse:not(.show) { display: none; }'), @@ -471,7 +471,7 @@ describe('collapse', () => { const localVue = CreateLocalVue() const App = localVue.extend({ render(h) { - return h('div', {}, [ + return h('div', [ // JSDOM supports getComputedStyle when using stylesheets (non responsive) // Although it appears to be picky about CSS definition ordering // https://github.com/jsdom/jsdom/blob/master/Changelog.md#030 diff --git a/src/components/collapse/package.json b/src/components/collapse/package.json index 9880bd0adc0..53bb7aef493 100644 --- a/src/components/collapse/package.json +++ b/src/components/collapse/package.json @@ -24,7 +24,7 @@ "props": [ { "prop": "isNav", - "description": "When set, signifies that hte collapse is bart of a navbar, enabling certain features for navbar support" + "description": "When set, signifies that the collapse is bart of a navbar, enabling certain features for navbar support" }, { "prop": "accordion", diff --git a/src/components/dropdown/dropdown-item.spec.js b/src/components/dropdown/dropdown-item.spec.js index caab23759ff..5a1a3a50149 100644 --- a/src/components/dropdown/dropdown-item.spec.js +++ b/src/components/dropdown/dropdown-item.spec.js @@ -96,7 +96,7 @@ describe('dropdown-item', () => { const App = localVue.extend({ router, render(h) { - return h('ul', {}, [ + return h('ul', [ // router-link h(BDropdownItem, { props: { to: '/a' } }, ['to-a']), // regular link diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 12ea2d28bb8..1c41b5947ae 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -433,7 +433,7 @@ describe('dropdown', () => { const App = localVue.extend({ render(h) { return h('div', { attrs: { id: 'container' } }, [ - h(BDropdown, { props: { id: 'test' } }, [h(BDropdownItem, {}, 'item')]), + h(BDropdown, { props: { id: 'test' } }, [h(BDropdownItem, 'item')]), h('input', { attrs: { id: 'input' } }) ]) } @@ -666,7 +666,7 @@ describe('dropdown', () => { const localVue = new CreateLocalVue() const App = localVue.extend({ render(h) { - return h('div', {}, [ + return h('div', [ h(BDropdown, { props: { id: 'test' } }, [ h(BDropdownItem, { attrs: { id: 'item-1' } }, 'item'), h(BDropdownItem, { attrs: { id: 'item-2' } }, 'item'), diff --git a/src/components/form-checkbox/form-checkbox.js b/src/components/form-checkbox/form-checkbox.js index 31cf9ac7aec..9b66df74f2e 100644 --- a/src/components/form-checkbox/form-checkbox.js +++ b/src/components/form-checkbox/form-checkbox.js @@ -68,13 +68,13 @@ export const BFormCheckbox = /*#__PURE__*/ Vue.extend({ } }, watch: { - computedLocalChecked(newVal, oldVal) { + computedLocalChecked(newVal) { this.$emit('input', newVal) if (this.$refs && this.$refs.input) { this.$emit('update:indeterminate', this.$refs.input.indeterminate) } }, - indeterminate(newVal, oldVal) { + indeterminate(newVal) { this.setIndeterminate(newVal) } }, diff --git a/src/components/form-group/form-group.js b/src/components/form-group/form-group.js index be2b47ee57c..7c7786dad62 100644 --- a/src/components/form-group/form-group.js +++ b/src/components/form-group/form-group.js @@ -447,7 +447,7 @@ export const BFormGroup = { return h( isFieldset ? 'fieldset' : isHorizontal ? BFormRow : 'div', data, - isHorizontal && isFieldset ? [h(BFormRow, {}, [label, content])] : [label, content] + isHorizontal && isFieldset ? [h(BFormRow, [label, content])] : [label, content] ) } } diff --git a/src/components/form-input/form-input.js b/src/components/form-input/form-input.js index 5e33d8ac0ad..47e736975ef 100644 --- a/src/components/form-input/form-input.js +++ b/src/components/form-input/form-input.js @@ -1,4 +1,6 @@ import Vue from '../../utils/vue' +import { arrayIncludes } from '../../utils/array' +import { eventOn, eventOff, eventOnOff } from '../../utils/events' import idMixin from '../../mixins/id' import formMixin from '../../mixins/form' import formSizeMixin from '../../mixins/form-size' @@ -6,8 +8,6 @@ import formStateMixin from '../../mixins/form-state' import formTextMixin from '../../mixins/form-text' import formSelectionMixin from '../../mixins/form-selection' import formValidityMixin from '../../mixins/form-validity' -import { arrayIncludes } from '../../utils/array' -import { eventOn, eventOff } from '../../utils/dom' // Valid supported input types const TYPES = [ @@ -101,20 +101,17 @@ export const BFormInput = /*#__PURE__*/ Vue.extend({ methods: { setWheelStopper(on) { const input = this.$el - // We use native events, so that we don't interfere with propgation - if (on) { - eventOn(input, 'focus', this.onWheelFocus) - eventOn(input, 'blur', this.onWheelBlur) - } else { - eventOff(input, 'focus', this.onWheelFocus) - eventOff(input, 'blur', this.onWheelBlur) + // We use native events, so that we don't interfere with propagation + eventOnOff(on, input, 'focus', this.onWheelFocus) + eventOnOff(on, input, 'blur', this.onWheelBlur) + if (!on) { eventOff(document, 'wheel', this.stopWheel) } }, - onWheelFocus(evt) { + onWheelFocus() { eventOn(document, 'wheel', this.stopWheel) }, - onWheelBlur(evt) { + onWheelBlur() { eventOff(document, 'wheel', this.stopWheel) }, stopWheel(evt) { diff --git a/src/components/form-input/form-input.spec.js b/src/components/form-input/form-input.spec.js index b97bbc13d1e..2297034868c 100644 --- a/src/components/form-input/form-input.spec.js +++ b/src/components/form-input/form-input.spec.js @@ -552,7 +552,7 @@ describe('form-input', () => { const wrapper = mount(BFormInput, { propsData: { value: 'abc', - formatter(value) { + formatter() { return false } }, diff --git a/src/components/form-radio/form-radio.js b/src/components/form-radio/form-radio.js index e48a72d05d8..2b0ccac5f06 100644 --- a/src/components/form-radio/form-radio.js +++ b/src/components/form-radio/form-radio.js @@ -44,7 +44,7 @@ export const BFormRadio = /*#__PURE__*/ Vue.extend({ }, watch: { // Radio Groups can only have a single value, so our watchers are simple - computedLocalChecked(newVal, oldVal) { + computedLocalChecked() { this.$emit('input', this.computedLocalChecked) } }, diff --git a/src/components/form-select/form-select.js b/src/components/form-select/form-select.js index 5ad5de41f98..85289bcb185 100644 --- a/src/components/form-select/form-select.js +++ b/src/components/form-select/form-select.js @@ -74,10 +74,10 @@ export const BFormSelect = /*#__PURE__*/ Vue.extend({ } }, watch: { - value(newVal, oldVal) { + value(newVal) { this.localValue = newVal }, - localValue(newVal, oldVal) { + localValue() { this.$emit('input', this.localValue) } }, diff --git a/src/components/form-tags/form-tags.js b/src/components/form-tags/form-tags.js index cdecbc6e176..cb508f4aac9 100644 --- a/src/components/form-tags/form-tags.js +++ b/src/components/form-tags/form-tags.js @@ -493,9 +493,7 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({ invalidTagText, duplicateTagText, isInvalid, - invalidTags, isDuplicate, - duplicateTags, disabled, placeholder, addButtonText, @@ -505,7 +503,7 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({ const h = this.$createElement // Make the list of tags - const $tags = tags.map((tag, idx) => { + const $tags = tags.map(tag => { tag = toString(tag) return h( BFormTag, diff --git a/src/components/form-textarea/form-textarea.js b/src/components/form-textarea/form-textarea.js index 1c874354cbf..c78cfe5cd9e 100644 --- a/src/components/form-textarea/form-textarea.js +++ b/src/components/form-textarea/form-textarea.js @@ -90,7 +90,7 @@ export const BFormTextarea = /*#__PURE__*/ Vue.extend({ } }, watch: { - localValue(newVal, oldVal) { + localValue() { this.setHeight() } }, diff --git a/src/components/jumbotron/package.json b/src/components/jumbotron/package.json index e10238e46fc..b0d2999152b 100644 --- a/src/components/jumbotron/package.json +++ b/src/components/jumbotron/package.json @@ -18,7 +18,7 @@ }, { "prop": "headerLevel", - "description": "Scaling factor of hte header. Values range from 1 to 5" + "description": "Scaling factor of the header. Values range from 1 to 5" }, { "prop": "lead", diff --git a/src/components/link/link.spec.js b/src/components/link/link.spec.js index 2efb1bd5b3a..8dc55e903f1 100644 --- a/src/components/link/link.spec.js +++ b/src/components/link/link.spec.js @@ -282,7 +282,7 @@ describe('b-link', () => { it('should emit "clicked::link" on $root when clicked on', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, [h(BLink, { props: { href: '/foo' } }, 'link')]) + return h('div', [h(BLink, { props: { href: '/foo' } }, 'link')]) } }) const spy = jest.fn() @@ -299,7 +299,7 @@ describe('b-link', () => { it('should NOT emit "clicked::link" on $root when clicked on when disabled', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, [h(BLink, { props: { href: '/foo', disabled: true } }, 'link')]) + return h('div', [h(BLink, { props: { href: '/foo', disabled: true } }, 'link')]) } }) const spy = jest.fn() @@ -335,7 +335,7 @@ describe('b-link', () => { router, components: { BLink }, render(h) { - return h('main', {}, [ + return h('main', [ // router-link h('b-link', { props: { to: '/a' } }, ['to-a']), // regular link diff --git a/src/components/media/media.js b/src/components/media/media.js index 83123b959fe..b5770a8d106 100644 --- a/src/components/media/media.js +++ b/src/components/media/media.js @@ -47,7 +47,7 @@ export const BMedia = /*#__PURE__*/ Vue.extend({ ) } - childNodes.push(h(BMediaBody, {}, $default)) + childNodes.push(h(BMediaBody, $default)) if ($aside && props.rightAlign) { childNodes.push( diff --git a/src/components/modal/README.md b/src/components/modal/README.md index 93f82cb7eef..2c3d2e5cfd8 100644 --- a/src/components/modal/README.md +++ b/src/components/modal/README.md @@ -972,7 +972,7 @@ method to generate VNodes. const messageVNode = h('div', { class: ['foobar'] }, [ h('p', { class: ['text-center'] }, [ ' Flashy ', - h('strong', {}, 'msgBoxOk'), + h('strong', 'msgBoxOk'), ' message ', ]), h('p', { class: ['text-center'] }, [h('b-spinner')]), @@ -1069,7 +1069,7 @@ already has focus within the ``. ```js export default { methods: { - focusMyElement(e) { + focusMyElement() { this.$refs.focusThis.focus() } } diff --git a/src/components/modal/helpers/bv-modal.js b/src/components/modal/helpers/bv-modal.js index a2ed0cafa0d..27d4875bdf9 100644 --- a/src/components/modal/helpers/bv-modal.js +++ b/src/components/modal/helpers/bv-modal.js @@ -29,7 +29,7 @@ const BASE_PROPS = [ ] // Fallback event resolver (returns undefined) -const defaultResolver = bvModalEvt => {} +const defaultResolver = () => {} // Map prop names to modal slot names const propsToSlots = { @@ -211,7 +211,7 @@ const plugin = Vue => { hideFooter: false, msgBoxContent: message } - return makeMsgBox(this._vm, message, props, bvModalEvt => { + return makeMsgBox(this._vm, message, props, () => { // Always resolve to true for OK return true }) diff --git a/src/components/modal/helpers/bv-modal.spec.js b/src/components/modal/helpers/bv-modal.spec.js index 44079eb931f..e8087d703bd 100644 --- a/src/components/modal/helpers/bv-modal.spec.js +++ b/src/components/modal/helpers/bv-modal.spec.js @@ -60,7 +60,7 @@ describe('$bvModal', () => { it('$bvModal.msgBoxOk() works', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, 'app') + return h('div', 'app') } }) const wrapper = mount(App, { @@ -122,7 +122,7 @@ describe('$bvModal', () => { it('$bvModal.msgBoxConfirm() works', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, 'app') + return h('div', 'app') } }) const wrapper = mount(App, { diff --git a/src/components/modal/helpers/modal-manager.js b/src/components/modal/helpers/modal-manager.js index 2fe251b5555..a6f33148a25 100644 --- a/src/components/modal/helpers/modal-manager.js +++ b/src/components/modal/helpers/modal-manager.js @@ -67,7 +67,7 @@ const ModalManager = /*#__PURE__*/ Vue.extend({ setAttr(document.body, 'data-modal-open-count', String(newCount)) } }, - modals(newVal, oldVal) { + modals(newVal) { this.checkScrollbar() requestAF(() => { this.updateModals(newVal || []) diff --git a/src/components/modal/modal.js b/src/components/modal/modal.js index 80372b80dcf..a82d9f58dba 100644 --- a/src/components/modal/modal.js +++ b/src/components/modal/modal.js @@ -5,17 +5,9 @@ import identity from '../../utils/identity' import observeDom from '../../utils/observe-dom' import { arrayIncludes, concat } from '../../utils/array' import { getComponentConfig } from '../../utils/config' -import { - closest, - contains, - eventOff, - eventOn, - isVisible, - requestAF, - select, - selectAll -} from '../../utils/dom' +import { closest, contains, isVisible, requestAF, select, selectAll } from '../../utils/dom' import { isBrowser } from '../../utils/env' +import { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff } from '../../utils/events' import { stripTags } from '../../utils/html' import { isString, isUndefinedOrNull } from '../../utils/inspect' import { HTMLElement } from '../../utils/safe-types' @@ -45,9 +37,6 @@ const OBSERVER_CONFIG = { attributeFilter: ['style', 'class'] } -// Options for DOM event listeners -const EVT_OPTIONS = { passive: true, capture: false } - // Query selector to find all tabbable elements // (includes tabindex="-1", which we filter out after) const TABABLE_SELECTOR = [ @@ -458,7 +447,7 @@ export const BModal = /*#__PURE__*/ Vue.extend({ } }, // Private method to create a BvModalEvent object - buildEvent(type, opts = {}) { + buildEvent(type, options = {}) { return new BvModalEvent(type, { // Default options cancelable: false, @@ -466,7 +455,7 @@ export const BModal = /*#__PURE__*/ Vue.extend({ relatedTarget: null, trigger: null, // Supplied options - ...opts, + ...options, // Options that can't be overridden vueTarget: this, componentId: this.safeId() @@ -671,12 +660,12 @@ export const BModal = /*#__PURE__*/ Vue.extend({ // And if it does, cancel the clickOut handler const modal = this.$refs.modal const onceModalMouseup = evt => { - eventOff(modal, 'mouseup', onceModalMouseup, EVT_OPTIONS) + eventOff(modal, 'mouseup', onceModalMouseup, EVENT_OPTIONS_NO_CAPTURE) if (evt.target === modal) { this.ignoreBackdropClick = true } } - eventOn(modal, 'mouseup', onceModalMouseup, EVT_OPTIONS) + eventOn(modal, 'mouseup', onceModalMouseup, EVENT_OPTIONS_NO_CAPTURE) }, onClickOut(evt) { if (this.ignoreBackdropClick) { @@ -1081,7 +1070,7 @@ export const BModal = /*#__PURE__*/ Vue.extend({ if (this.static) { return this.lazy && this.isHidden ? h() : this.makeModal(h) } else { - return this.isHidden ? h() : h(BTransporterSingle, {}, [this.makeModal(h)]) + return this.isHidden ? h() : h(BTransporterSingle, [this.makeModal(h)]) } } }) diff --git a/src/components/modal/modal.spec.js b/src/components/modal/modal.spec.js index 677abde0e81..167d5e5f119 100644 --- a/src/components/modal/modal.spec.js +++ b/src/components/modal/modal.spec.js @@ -994,7 +994,7 @@ describe('modal', () => { it('returns focus to previous active element when return focus not set and not using v-b-toggle', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, [ + return h('div', [ h('button', { class: 'trigger', attrs: { id: 'trigger', type: 'button' } }, 'trigger'), h(BModal, { props: { static: true, id: 'test', visible: false } }, 'modal content') ]) @@ -1071,7 +1071,7 @@ describe('modal', () => { it('returns focus to element specified in toggle() method', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, [ + return h('div', [ h('button', { class: 'trigger', attrs: { id: 'trigger', type: 'button' } }, 'trigger'), h( 'button', @@ -1160,7 +1160,7 @@ describe('modal', () => { it('if focus leaves modal it returns to modal', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, [ + return h('div', [ h('button', { attrs: { id: 'button', type: 'button' } }, 'Button'), h(BModal, { props: { static: true, id: 'test', visible: true } }, 'Modal content') ]) @@ -1247,7 +1247,7 @@ describe('modal', () => { it('it allows focus for elements when "no-enforce-focus" enabled', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, [ + return h('div', [ h('button', { attrs: { id: 'button1', type: 'button' } }, 'Button 1'), h('button', { attrs: { id: 'button2', type: 'button' } }, 'Button 2'), h( @@ -1321,7 +1321,7 @@ describe('modal', () => { it('it allows focus for elements in "ignore-enforce-focus-selector" prop', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, [ + return h('div', [ h('button', { attrs: { id: 'button1', type: 'button' } }, 'Button 1'), h('button', { attrs: { id: 'button2', type: 'button' } }, 'Button 2'), h( diff --git a/src/components/nav/nav-text.js b/src/components/nav/nav-text.js index f75aae55aff..696243559f9 100644 --- a/src/components/nav/nav-text.js +++ b/src/components/nav/nav-text.js @@ -8,7 +8,7 @@ export const BNavText = /*#__PURE__*/ Vue.extend({ name: 'BNavText', functional: true, props, - render(h, { props, data, children }) { + render(h, { data, children }) { return h('li', mergeData(data, { staticClass: 'navbar-text' }), children) } }) diff --git a/src/components/pagination-nav/pagination-nav.js b/src/components/pagination-nav/pagination-nav.js index ee4f4570e95..638e4302297 100644 --- a/src/components/pagination-nav/pagination-nav.js +++ b/src/components/pagination-nav/pagination-nav.js @@ -99,12 +99,12 @@ export const BPaginationNav = /*#__PURE__*/ Vue.extend({ } }, watch: { - numberOfPages(newVal, oldVal) { + numberOfPages() { this.$nextTick(() => { this.setNumberOfPages() }) }, - pages(newVal, oldVal) { + pages() { this.$nextTick(() => { this.setNumberOfPages() }) @@ -116,7 +116,7 @@ export const BPaginationNav = /*#__PURE__*/ Vue.extend({ mounted() { if (this.$router) { // We only add the watcher if vue router is detected - this.$watch('$route', (to, from) => { + this.$watch('$route', () => { this.$nextTick(() => { requestAF(() => { this.guessCurrentPage() diff --git a/src/components/pagination/pagination.js b/src/components/pagination/pagination.js index f59acf713c9..94c659b2d8c 100644 --- a/src/components/pagination/pagination.js +++ b/src/components/pagination/pagination.js @@ -131,7 +131,7 @@ export const BPagination = /*#__PURE__*/ Vue.extend({ makePage(pageNum) { return pageNum }, - linkProps(pageNum) { + linkProps() { // Always '#' for pagination component return { href: '#' } } diff --git a/src/components/table/README.md b/src/components/table/README.md index a2e454f50a3..024a325d401 100644 --- a/src/components/table/README.md +++ b/src/components/table/README.md @@ -578,16 +578,16 @@ values: `sm`, `md`, `lg`, or `xl`. - Using props `responsive` and `fixed` together will **not** work as expected. Fixed table layout uses the first row (table header in this case) to compute the width required by each column (and the overall table width) to fit within the width of the parent container — without taking - cells in the `` into consideration — resulting in table that may not be resposive. To - get around this limitation, you would need to specify widths for the columns (or certain columns) - via one of the following methods: + cells in the `` into consideration — resulting in table that may not be responsive. + To get around this limitation, you would need to specify widths for the columns (or certain + columns) via one of the following methods: - Use `` elements within the [`table-colgroup` slot](#table-colgroup) that have widths set (e.g. ``), or - Wrap header cells in `
` elements, via the use of [custom header rendering](#header-and-footer-custom-rendering-via-scoped-slots), which have a minimum width set on them, or - - Use the `thStyle` property of the [field definition object](#field-definition-reference) to - set a width for the column(s), or + - Use the `thStyle` property of the [field definition object](#field-definition-reference) to set + a width for the column(s), or - Use custom CSS to define classes to apply to the columns to set widths, via the `thClass` or `class` properties of the [field definition object](#field-definition-reference). @@ -2221,7 +2221,7 @@ method. ```js -function myProvider(ctx) { +function myProvider() { let items = [] // Perform any items processing needed @@ -2306,7 +2306,7 @@ function should handle errors from data sources and return an empty array to ` + ```js export default { methods: { diff --git a/src/components/table/helpers/mixin-filtering.js b/src/components/table/helpers/mixin-filtering.js index c2684334c49..59824f66bf3 100644 --- a/src/components/table/helpers/mixin-filtering.js +++ b/src/components/table/helpers/mixin-filtering.js @@ -98,7 +98,7 @@ export default { }, watch: { // Watch for debounce being set to 0 - computedFilterDebounce(newVal, oldVal) { + computedFilterDebounce(newVal) { if (!newVal && this.$_filterTimer) { clearTimeout(this.$_filterTimer) this.$_filterTimer = null @@ -110,7 +110,7 @@ export default { // We need a deep watcher in case the user passes // an object when using `filter-function` deep: true, - handler(newCriteria, oldCriteria) { + handler(newCriteria) { const timeout = this.computedFilterDebounce clearTimeout(this.$_filterTimer) this.$_filterTimer = null @@ -127,7 +127,7 @@ export default { }, // Watch for changes to the filter criteria and filtered items vs `localItems` // Set visual state and emit events as required - filteredCheck({ filteredItems, localItems, localFilter }) { + filteredCheck({ filteredItems, localFilter }) { // Determine if the dataset is filtered or not let isFiltered = false if (!localFilter) { diff --git a/src/components/table/helpers/mixin-provider.js b/src/components/table/helpers/mixin-provider.js index b56a762f25e..1dd3111bb62 100644 --- a/src/components/table/helpers/mixin-provider.js +++ b/src/components/table/helpers/mixin-provider.js @@ -68,7 +68,7 @@ export default { }, watch: { // Provider update triggering - items(newVal, oldVal) { + items(newVal) { // If a new provider has been specified, trigger an update if (this.hasProvider || isFunction(newVal)) { this.$nextTick(this._providerUpdate) diff --git a/src/components/table/helpers/mixin-selectable.js b/src/components/table/helpers/mixin-selectable.js index 9051a3386d9..489bcdf5148 100644 --- a/src/components/table/helpers/mixin-selectable.js +++ b/src/components/table/helpers/mixin-selectable.js @@ -91,14 +91,14 @@ export default { this.clearSelected() } }, - selectable(newVal, oldVal) { + selectable(newVal) { this.clearSelected() this.setSelectionHandlers(newVal) }, - selectMode(newVal, oldVal) { + selectMode() { this.clearSelected() }, - hasSelectableRowClick(newVal, oldVal) { + hasSelectableRowClick(newVal) { this.clearSelected() this.setSelectionHandlers(!newVal) }, @@ -151,7 +151,7 @@ export default { const length = this.computedItems.length if (this.isSelectable && length > 0) { this.selectedLastClicked = -1 - this.selectedRows = this.selectableIsMultiSelect ? range(length).map(i => true) : [true] + this.selectedRows = this.selectableIsMultiSelect ? range(length).map(() => true) : [true] } }, isRowSelected(index) { diff --git a/src/components/table/helpers/mixin-sorting.js b/src/components/table/helpers/mixin-sorting.js index 36b0a98255d..385ec9b0f47 100644 --- a/src/components/table/helpers/mixin-sorting.js +++ b/src/components/table/helpers/mixin-sorting.js @@ -141,7 +141,7 @@ export default { } }, watch: { - isSortable(newVal, oldVal) /* istanbul ignore next: pain in the butt to test */ { + isSortable(newVal) /* istanbul ignore next: pain in the butt to test */ { if (newVal) { if (this.isSortable) { this.$on('head-clicked', this.handleSort) @@ -150,14 +150,14 @@ export default { this.$off('head-clicked', this.handleSort) } }, - sortDesc(newVal, oldVal) { + sortDesc(newVal) { if (newVal === this.localSortDesc) { /* istanbul ignore next */ return } this.localSortDesc = newVal || false }, - sortBy(newVal, oldVal) { + sortBy(newVal) { if (newVal === this.localSortBy) { /* istanbul ignore next */ return diff --git a/src/components/table/helpers/mixin-table-renderer.js b/src/components/table/helpers/mixin-table-renderer.js index 0f580a64ae7..451c7fae640 100644 --- a/src/components/table/helpers/mixin-table-renderer.js +++ b/src/components/table/helpers/mixin-table-renderer.js @@ -165,7 +165,7 @@ export default { const $content = [] if (this.isTableSimple) { - $content.push(this.normalizeSlot('default', {})) + $content.push(this.normalizeSlot('default')) } else { // Build the `
` (from caption mixin) $content.push(this.renderCaption ? this.renderCaption() : null) diff --git a/src/components/table/helpers/mixin-tbody-row.js b/src/components/table/helpers/mixin-tbody-row.js index f430ea68f7d..ac417e2b15c 100644 --- a/src/components/table/helpers/mixin-tbody-row.js +++ b/src/components/table/helpers/mixin-tbody-row.js @@ -171,7 +171,7 @@ export default { let $childNodes = slotName ? this.normalizeSlot(slotName, slotScope) : toString(formatted) if (this.isStacked) { // We wrap in a DIV to ensure rendered as a single cell when visually stacked! - $childNodes = [h('div', {}, [$childNodes])] + $childNodes = [h('div', [$childNodes])] } // Render either a td or th cell return h(cellTag, data, [$childNodes]) diff --git a/src/components/table/table-caption.spec.js b/src/components/table/table-caption.spec.js index 0ca3f9784a0..6fc67573233 100644 --- a/src/components/table/table-caption.spec.js +++ b/src/components/table/table-caption.spec.js @@ -50,7 +50,7 @@ describe('table > caption', () => { scopedSlots: { 'table-caption': function(props) { scope = props - return this.$createElement('b', {}, 'foobar') + return this.$createElement('b', 'foobar') } } }) diff --git a/src/components/table/table-selectable.spec.js b/src/components/table/table-selectable.spec.js index 0f1ce80c44b..4f079244a7f 100644 --- a/src/components/table/table-selectable.spec.js +++ b/src/components/table/table-selectable.spec.js @@ -53,7 +53,7 @@ describe('table > row select', () => { items: testItems }, listeners: { - 'row-clicked': (item, index, evt) => {} + 'row-clicked': () => {} } }) expect(wrapper).toBeDefined() diff --git a/src/components/table/table-tbody-transition.spec.js b/src/components/table/table-tbody-transition.spec.js index 3714f7d363b..091629a0f11 100644 --- a/src/components/table/table-tbody-transition.spec.js +++ b/src/components/table/table-tbody-transition.spec.js @@ -55,10 +55,10 @@ describe('table > tbody transition', () => { fields: testFields, items: testItems, tbodyTransitionHandlers: { - onBeforeEnter: el => {}, - onAfterEnter: el => {}, - onBeforeLeave: el => {}, - onAfterLeave: el => {} + onBeforeEnter: () => {}, + onAfterEnter: () => {}, + onBeforeLeave: () => {}, + onAfterLeave: () => {} } }, stubs: { diff --git a/src/components/table/tbody.js b/src/components/table/tbody.js index 7b1033ead86..5f2374bf8fc 100644 --- a/src/components/table/tbody.js +++ b/src/components/table/tbody.js @@ -90,7 +90,7 @@ export const BTbody = /*#__PURE__*/ Vue.extend({ return h( this.isTransitionGroup ? 'transition-group' : 'tbody', data, - this.normalizeSlot('default', {}) + this.normalizeSlot('default') ) } }) diff --git a/src/components/table/tfoot.js b/src/components/table/tfoot.js index 75f8b936740..c5bcfc09fb8 100644 --- a/src/components/table/tfoot.js +++ b/src/components/table/tfoot.js @@ -75,7 +75,7 @@ export const BTfoot = /*#__PURE__*/ Vue.extend({ // Pass down any native listeners on: this.$listeners }, - this.normalizeSlot('default', {}) + this.normalizeSlot('default') ) } }) diff --git a/src/components/table/thead.js b/src/components/table/thead.js index cf393dd1362..4f89683a003 100644 --- a/src/components/table/thead.js +++ b/src/components/table/thead.js @@ -78,7 +78,7 @@ export const BThead = /*#__PURE__*/ Vue.extend({ // Pass down any native listeners on: this.$listeners }, - this.normalizeSlot('default', {}) + this.normalizeSlot('default') ) } }) diff --git a/src/components/table/tr.js b/src/components/table/tr.js index 2a973deb442..ab58d137bcb 100644 --- a/src/components/table/tr.js +++ b/src/components/table/tr.js @@ -23,7 +23,7 @@ export const BTr = /*#__PURE__*/ Vue.extend({ }, inject: { bvTableRowGroup: { - defaut() /* istanbul ignore next */ { + default() /* istanbul ignore next */ { return {} } } @@ -100,7 +100,7 @@ export const BTr = /*#__PURE__*/ Vue.extend({ // Pass native listeners to child on: this.$listeners }, - this.normalizeSlot('default', {}) + this.normalizeSlot('default') ) } }) diff --git a/src/components/tabs/tab.js b/src/components/tabs/tab.js index 4fd4e5f8010..a8015a97fb1 100644 --- a/src/components/tabs/tab.js +++ b/src/components/tabs/tab.js @@ -85,7 +85,7 @@ export const BTab = /*#__PURE__*/ Vue.extend({ } }, watch: { - localActive(newVal, oldVal) { + localActive(newVal) { // Make 'active' prop work with `.sync` modifier this.$emit('update:active', newVal) }, diff --git a/src/components/tabs/tabs.js b/src/components/tabs/tabs.js index 0e186256b75..7cc0ac960eb 100644 --- a/src/components/tabs/tabs.js +++ b/src/components/tabs/tabs.js @@ -245,11 +245,11 @@ export const BTabs = /*#__PURE__*/ Vue.extend({ } }, watch: { - currentTab(val, old) { + currentTab(newVal) { let index = -1 // Ensure only one tab is active at most this.tabs.forEach((tab, idx) => { - if (val === idx && !tab.disabled) { + if (newVal === idx && !tab.disabled) { tab.localActive = true index = idx } else { @@ -259,17 +259,17 @@ export const BTabs = /*#__PURE__*/ Vue.extend({ // Update the v-model this.$emit('input', index) }, - value(val, old) { - if (val !== old) { - val = parseInt(val, 10) - val = isNaN(val) ? -1 : val - old = parseInt(old, 10) || 0 + value(newVal, oldVal) { + if (newVal !== oldVal) { + newVal = parseInt(newVal, 10) + newVal = isNaN(newVal) ? -1 : newVal + oldVal = parseInt(oldVal, 10) || 0 const tabs = this.tabs - if (tabs[val] && !tabs[val].disabled) { - this.activateTab(tabs[val]) + if (tabs[newVal] && !tabs[newVal].disabled) { + this.activateTab(tabs[newVal]) } else { // Try next or prev tabs - if (val < old) { + if (newVal < oldVal) { this.previousTab() } else { this.nextTab() @@ -277,7 +277,7 @@ export const BTabs = /*#__PURE__*/ Vue.extend({ } } }, - registeredTabs(newVal, oldVal) { + registeredTabs() { // Each b-tab will register/unregister itself. // We use this to detect when tabs are added/removed // to trigger the update of the tabs. @@ -300,7 +300,7 @@ export const BTabs = /*#__PURE__*/ Vue.extend({ }) } }, - isMounted(newVal, oldVal) { + isMounted(newVal) { // Trigger an update after mounted. Needed for tabs inside lazy modals. if (newVal) { requestAF(() => { @@ -453,7 +453,7 @@ export const BTabs = /*#__PURE__*/ Vue.extend({ } // Set the current tab state to active - tabs.forEach((tab, idx) => { + tabs.forEach(tab => { // tab.localActive = idx === tabIndex && !tab.disabled tab.localActive = false }) diff --git a/src/components/tabs/tabs.spec.js b/src/components/tabs/tabs.spec.js index dc001b9cd17..ca544ae3554 100644 --- a/src/components/tabs/tabs.spec.js +++ b/src/components/tabs/tabs.spec.js @@ -104,7 +104,7 @@ describe('tabs', () => { it('sets correct tab active when first tab is disabled', async () => { const App = Vue.extend({ render(h) { - return h(BTabs, {}, [ + return h(BTabs, [ h(BTab, { props: { disabled: true } }, 'tab 0'), h(BTab, { props: {} }, 'tab 1'), h(BTab, { props: {} }, 'tab 2') @@ -136,7 +136,7 @@ describe('tabs', () => { it('sets current index based on active prop of b-tab', async () => { const App = Vue.extend({ render(h) { - return h(BTabs, {}, [ + return h(BTabs, [ h(BTab, { props: { active: false } }, 'tab 0'), h(BTab, { props: { active: true } }, 'tab 1'), h(BTab, { props: { active: false } }, 'tab 2') @@ -168,7 +168,7 @@ describe('tabs', () => { it('selects first non-disabled tab when active tab disabled', async () => { const App = Vue.extend({ render(h) { - return h(BTabs, {}, [ + return h(BTabs, [ h(BTab, { props: { active: false, disabled: true } }, 'tab 0'), h(BTab, { props: { active: true } }, 'tab 1'), h(BTab, { props: { active: false } }, 'tab 2') @@ -694,7 +694,7 @@ describe('tabs', () => { expect(tabVm).toBeDefined() // Change title slot content - tabVm.$slots.title = [tabVm.$createElement('span', {}, 'foobar')] + tabVm.$slots.title = [tabVm.$createElement('span', 'foobar')] tabVm.$forceUpdate() await waitNT(wrapper.vm) await waitRAF() diff --git a/src/components/toast/README.md b/src/components/toast/README.md index f7f2b7347f0..1291b9fc5a0 100644 --- a/src/components/toast/README.md +++ b/src/components/toast/README.md @@ -452,7 +452,7 @@ for generating more complex toast content: [ h('b-spinner', { props: { type: 'grow', small: true } }), ' Flashy ', - h('strong', {}, 'toast'), + h('strong', 'toast'), ` message #${this.count} `, h('b-spinner', { props: { type: 'grow', small: true } }) ] diff --git a/src/components/toast/helpers/bv-toast.spec.js b/src/components/toast/helpers/bv-toast.spec.js index f1e721b51a1..f717feb7d53 100644 --- a/src/components/toast/helpers/bv-toast.spec.js +++ b/src/components/toast/helpers/bv-toast.spec.js @@ -74,7 +74,7 @@ describe('$bvToast', () => { it('$bvModal.toast() works', async () => { const App = localVue.extend({ render(h) { - return h('div', {}, 'app') + return h('div', 'app') } }) const wrapper = mount(App, { diff --git a/src/components/toast/package.json b/src/components/toast/package.json index e55f6bebba6..14e7d6c72d9 100644 --- a/src/components/toast/package.json +++ b/src/components/toast/package.json @@ -46,7 +46,7 @@ }, { "prop": "noHoverPause", - "description": "When set, disables the pausing of hte auto hide delay when the mouse hovers the toast" + "description": "When set, disables the pausing of the auto hide delay when the mouse hovers the toast" }, { "prop": "solid", diff --git a/src/components/toast/toast.js b/src/components/toast/toast.js index 4c168e13339..7eb5d6c42d4 100644 --- a/src/components/toast/toast.js +++ b/src/components/toast/toast.js @@ -3,7 +3,8 @@ import { Portal, Wormhole } from 'portal-vue' import BVTransition from '../../utils/bv-transition' import { BvEvent } from '../../utils/bv-event.class' import { getComponentConfig } from '../../utils/config' -import { requestAF, eventOn, eventOff } from '../../utils/dom' +import { requestAF } from '../../utils/dom' +import { EVENT_OPTIONS_NO_CAPTURE, eventOnOff } from '../../utils/events' import { toInteger } from '../../utils/number' import idMixin from '../../mixins/id' import listenOnRootMixin from '../../mixins/listen-on-root' @@ -19,8 +20,6 @@ const NAME = 'BToast' const MIN_DURATION = 1000 -const EVENT_OPTIONS = { passive: true, capture: false } - // --- Props --- export const props = { @@ -168,7 +167,7 @@ export const BToast = /*#__PURE__*/ Vue.extend({ this.$emit('change', newVal) } }, - toaster(newVal) /* istanbul ignore next */ { + toaster() /* istanbul ignore next */ { // If toaster target changed, make sure toaster exists this.$nextTick(this.ensureToaster) }, @@ -246,12 +245,12 @@ export const BToast = /*#__PURE__*/ Vue.extend({ }) } }, - buildEvent(type, opts = {}) { + buildEvent(type, options = {}) { return new BvEvent(type, { cancelable: false, target: this.$el || null, relatedTarget: null, - ...opts, + ...options, vueTarget: this, componentId: this.safeId() }) @@ -290,12 +289,11 @@ export const BToast = /*#__PURE__*/ Vue.extend({ this.timer = null }, setHoverHandler(on) { - const method = on ? eventOn : eventOff const el = this.$refs['b-toast'] - method(el, 'mouseenter', this.onPause, EVENT_OPTIONS) - method(el, 'mouseleave', this.onUnPause, EVENT_OPTIONS) + eventOnOff(on, el, 'mouseenter', this.onPause, EVENT_OPTIONS_NO_CAPTURE) + eventOnOff(on, el, 'mouseleave', this.onUnPause, EVENT_OPTIONS_NO_CAPTURE) }, - onPause(evt) { + onPause() { // Determine time remaining, and then pause timer if (this.noAutoHide || this.noHoverPause || !this.timer || this.resumeDismiss) { return @@ -306,7 +304,7 @@ export const BToast = /*#__PURE__*/ Vue.extend({ this.resumeDismiss = Math.max(this.computedDuration - passed, MIN_DURATION) } }, - onUnPause(evt) { + onUnPause() { // Restart timer with max of time remaining or 1 second if (this.noAutoHide || this.noHoverPause || !this.resumeDismiss) { this.resumeDismiss = this.dismissStarted = 0 @@ -359,7 +357,7 @@ export const BToast = /*#__PURE__*/ Vue.extend({ h(BButtonClose, { staticClass: 'ml-auto mb-1', on: { - click: evt => { + click: () => { this.hide() } } diff --git a/src/components/tooltip/helpers/bv-tooltip.js b/src/components/tooltip/helpers/bv-tooltip.js index 4c422ee00ad..e35f657a8f0 100644 --- a/src/components/tooltip/helpers/bv-tooltip.js +++ b/src/components/tooltip/helpers/bv-tooltip.js @@ -9,21 +9,20 @@ import looseEqual from '../../../utils/loose-equal' import noop from '../../../utils/noop' import { arrayIncludes, concat, from as arrayFrom } from '../../../utils/array' import { - isElement, - isDisabled, - isVisible, closest, contains, - select, - getById, - hasClass, getAttr, + getById, hasAttr, - setAttr, + hasClass, + isDisabled, + isElement, + isVisible, removeAttr, - eventOn, - eventOff + select, + setAttr } from '../../../utils/dom' +import { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff, eventOnOff } from '../../../utils/events' import { isFunction, isNumber, @@ -48,9 +47,6 @@ const MODAL_CLOSE_EVENT = 'bv::modal::hidden' const DROPDOWN_CLASS = 'dropdown' const DROPDOWN_OPEN_SELECTOR = '.dropdown-menu.show' -// Options for Native Event Listeners (since we never call preventDefault) -const EvtOpts = { passive: true, capture: false } - // Data specific to popper and template // We don't use props, as we need reactivity (we can't pass reactive props) const templateData = { @@ -482,7 +478,7 @@ export const BVTooltip = /*#__PURE__*/ Vue.extend({ // Destroy the template this.destroyTemplate() // Emit a non-cancelable BvEvent 'shown' - this.emitEvent(this.buildEvent('hidden', {})) + this.emitEvent(this.buildEvent('hidden')) }, // --- Utility methods --- getTarget() { @@ -610,7 +606,7 @@ export const BVTooltip = /*#__PURE__*/ Vue.extend({ } }, // --- BvEvent helpers --- - buildEvent(type, opts = {}) { + buildEvent(type, options = {}) { // Defaults to a non-cancellable event return new BvEvent(type, { cancelable: false, @@ -619,7 +615,7 @@ export const BVTooltip = /*#__PURE__*/ Vue.extend({ componentId: this.computedId, vueTarget: this, // Add in option overrides - ...opts + ...options }) }, emitEvent(bvEvt) { @@ -645,17 +641,17 @@ export const BVTooltip = /*#__PURE__*/ Vue.extend({ // Set up our listeners on the target trigger element this.computedTriggers.forEach(trigger => { if (trigger === 'click') { - eventOn(el, 'click', this.handleEvent, EvtOpts) + eventOn(el, 'click', this.handleEvent, EVENT_OPTIONS_NO_CAPTURE) } else if (trigger === 'focus') { - eventOn(el, 'focusin', this.handleEvent, EvtOpts) - eventOn(el, 'focusout', this.handleEvent, EvtOpts) + eventOn(el, 'focusin', this.handleEvent, EVENT_OPTIONS_NO_CAPTURE) + eventOn(el, 'focusout', this.handleEvent, EVENT_OPTIONS_NO_CAPTURE) } else if (trigger === 'blur') { // Used to close $tip when element looses focus /* istanbul ignore next */ - eventOn(el, 'focusout', this.handleEvent, EvtOpts) + eventOn(el, 'focusout', this.handleEvent, EVENT_OPTIONS_NO_CAPTURE) } else if (trigger === 'hover') { - eventOn(el, 'mouseenter', this.handleEvent, EvtOpts) - eventOn(el, 'mouseleave', this.handleEvent, EvtOpts) + eventOn(el, 'mouseenter', this.handleEvent, EVENT_OPTIONS_NO_CAPTURE) + eventOn(el, 'mouseleave', this.handleEvent, EVENT_OPTIONS_NO_CAPTURE) } }, this) }, @@ -669,7 +665,7 @@ export const BVTooltip = /*#__PURE__*/ Vue.extend({ // Clear out any active target listeners events.forEach(evt => { - target && eventOff(target, evt, this.handleEvent, EvtOpts) + target && eventOff(target, evt, this.handleEvent, EVENT_OPTIONS_NO_CAPTURE) }, this) }, setRootListener(on) { @@ -723,9 +719,8 @@ export const BVTooltip = /*#__PURE__*/ Vue.extend({ // 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) { - const method = on ? eventOn : eventOff arrayFrom(document.body.children).forEach(el => { - method(el, 'mouseover', this.$_noop) + eventOnOff(on, el, 'mouseover', this.$_noop) }) } }, @@ -827,7 +822,7 @@ export const BVTooltip = /*#__PURE__*/ Vue.extend({ this.enable() } }, - click(evt) { + click() { if (!this.$_enabled || this.dropdownOpen()) { /* istanbul ignore next */ return diff --git a/src/components/tooltip/tooltip.js b/src/components/tooltip/tooltip.js index e17b1229919..1ef3f1895c0 100644 --- a/src/components/tooltip/tooltip.js +++ b/src/components/tooltip/tooltip.js @@ -154,18 +154,18 @@ export const BTooltip = /*#__PURE__*/ Vue.extend({ } } }, - disabled(newVal, oldVal) { + disabled(newVal) { if (newVal) { this.doDisable() } else { this.doEnable() } }, - localShow(show, oldVal) { + localShow(newVal) { // TODO: May need to be done in a `$nextTick()` - this.$emit('update:show', show) + this.$emit('update:show', newVal) }, - templateData(newVal, oldVal) { + templateData() { this.$nextTick(() => { if (this.$_bv_toolpop) { this.$_bv_toolpop.updateData(this.templateData) @@ -173,7 +173,7 @@ export const BTooltip = /*#__PURE__*/ Vue.extend({ }) }, // Watchers for title/content props (prop changes do not trigger the `updated()` hook) - templateTitleContent(newVal, oldVal) { + templateTitleContent() { this.$nextTick(this.updateContent) } }, @@ -313,7 +313,7 @@ export const BTooltip = /*#__PURE__*/ Vue.extend({ doClose() { this.localShow && this.$_bv_toolpop && this.$_bv_toolpop.hide() }, - doDisable(evt) { + doDisable() { this.$_bv_toolpop && this.$_bv_toolpop.disable() }, doEnable() { diff --git a/src/directives/modal/modal.js b/src/directives/modal/modal.js index d112b8fd5c3..21ee73e1c39 100644 --- a/src/directives/modal/modal.js +++ b/src/directives/modal/modal.js @@ -1,14 +1,6 @@ import KeyCodes from '../../utils/key-codes' -import { - eventOn, - eventOff, - getAttr, - hasAttr, - isDisabled, - matches, - select, - setAttr -} from '../../utils/dom' +import { getAttr, hasAttr, isDisabled, matches, select, setAttr } from '../../utils/dom' +import { EVENT_OPTIONS_PASSIVE, eventOn, eventOff } from '../../utils/events' import { isString } from '../../utils/inspect' import { keys } from '../../utils/object' @@ -18,8 +10,6 @@ const EVENT_SHOW = 'bv::show::modal' // Prop name we use to store info on root element const PROPERTY = '__bv_modal_directive__' -const EVENT_OPTS = { passive: true } - const getTarget = ({ modifiers = {}, arg, value }) => { // Try value, then arg, otherwise pick last modifier return isString(value) ? value : isString(arg) ? arg : keys(modifiers).reverse()[0] @@ -68,11 +58,11 @@ const bind = (el, binding, vnode) => { // If element is not a button, we add `role="button"` for accessibility setRole(trigger) // Listen for click events - eventOn(trigger, 'click', handler, EVENT_OPTS) + eventOn(trigger, 'click', handler, EVENT_OPTIONS_PASSIVE) if (trigger.tagName !== 'BUTTON' && getAttr(trigger, 'role') === 'button') { // If trigger isn't a button but has role button, // we also listen for `keydown.space` && `keydown.enter` - eventOn(trigger, 'keydown', handler, EVENT_OPTS) + eventOn(trigger, 'keydown', handler, EVENT_OPTIONS_PASSIVE) } } } @@ -82,10 +72,10 @@ const unbind = el => { const trigger = oldProp.trigger const handler = oldProp.handler if (trigger && handler) { - eventOff(trigger, 'click', handler, EVENT_OPTS) - eventOff(trigger, 'keydown', handler, EVENT_OPTS) - eventOff(el, 'click', handler, EVENT_OPTS) - eventOff(el, 'keydown', handler, EVENT_OPTS) + eventOff(trigger, 'click', handler, EVENT_OPTIONS_PASSIVE) + eventOff(trigger, 'keydown', handler, EVENT_OPTIONS_PASSIVE) + eventOff(el, 'click', handler, EVENT_OPTIONS_PASSIVE) + eventOff(el, 'keydown', handler, EVENT_OPTIONS_PASSIVE) } delete el[PROPERTY] } diff --git a/src/directives/scrollspy/scrollspy.class.js b/src/directives/scrollspy/scrollspy.class.js index dbcd2f31307..de692c0ac8c 100644 --- a/src/directives/scrollspy/scrollspy.class.js +++ b/src/directives/scrollspy/scrollspy.class.js @@ -4,22 +4,21 @@ import observeDom from '../../utils/observe-dom' import { + addClass, + closest, + getAttr, + getBCR, + hasClass, isElement, isVisible, - closest, matches, - getBCR, offset, position, - selectAll, - select, - hasClass, - addClass, removeClass, - getAttr, - eventOn, - eventOff + select, + selectAll } from '../../utils/dom' +import { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff } from '../../utils/events' import { isString, isUndefined } from '../../utils/inspect' import { toString as objectToString } from '../../utils/object' import { warn } from '../../utils/warn' @@ -79,9 +78,6 @@ const TransitionEndEvents = [ 'oTransitionEnd' ] -// Options for events -const EventOptions = { passive: true, capture: false } - /* * Utility Methods */ @@ -195,13 +191,13 @@ class ScrollSpy /* istanbul ignore next: not easy to test */ { listen() { const scroller = this.getScroller() if (scroller && scroller.tagName !== 'BODY') { - eventOn(scroller, 'scroll', this, EventOptions) + eventOn(scroller, 'scroll', this, EVENT_OPTIONS_NO_CAPTURE) } - eventOn(window, 'scroll', this, EventOptions) - eventOn(window, 'resize', this, EventOptions) - eventOn(window, 'orientationchange', this, EventOptions) + eventOn(window, 'scroll', this, EVENT_OPTIONS_NO_CAPTURE) + eventOn(window, 'resize', this, EVENT_OPTIONS_NO_CAPTURE) + eventOn(window, 'orientationchange', this, EVENT_OPTIONS_NO_CAPTURE) TransitionEndEvents.forEach(evtName => { - eventOn(window, evtName, this, EventOptions) + eventOn(window, evtName, this, EVENT_OPTIONS_NO_CAPTURE) }) this.setObservers(true) // Schedule a refresh @@ -212,13 +208,13 @@ class ScrollSpy /* istanbul ignore next: not easy to test */ { const scroller = this.getScroller() this.setObservers(false) if (scroller && scroller.tagName !== 'BODY') { - eventOff(scroller, 'scroll', this, EventOptions) + eventOff(scroller, 'scroll', this, EVENT_OPTIONS_NO_CAPTURE) } - eventOff(window, 'scroll', this, EventOptions) - eventOff(window, 'resize', this, EventOptions) - eventOff(window, 'orientationchange', this, EventOptions) + eventOff(window, 'scroll', this, EVENT_OPTIONS_NO_CAPTURE) + eventOff(window, 'resize', this, EVENT_OPTIONS_NO_CAPTURE) + eventOff(window, 'orientationchange', this, EVENT_OPTIONS_NO_CAPTURE) TransitionEndEvents.forEach(evtName => { - eventOff(window, evtName, this, EventOptions) + eventOff(window, evtName, this, EVENT_OPTIONS_NO_CAPTURE) }) } diff --git a/src/icons/iconstack.spec.js b/src/icons/iconstack.spec.js index b3c11f854c9..5e761d29375 100644 --- a/src/icons/iconstack.spec.js +++ b/src/icons/iconstack.spec.js @@ -3,7 +3,7 @@ import { BIconstack } from './iconstack' describe('icons > b-iconstack', () => { it('has expected default structure', async () => { - const wrapper = mount(BIconstack, {}) + const wrapper = mount(BIconstack) expect(wrapper.exists()).toBe(true) expect(wrapper.is('svg')).toBe(true) diff --git a/src/mixins/click-out.js b/src/mixins/click-out.js index 22fe08a559b..e9782ac2c1a 100644 --- a/src/mixins/click-out.js +++ b/src/mixins/click-out.js @@ -1,6 +1,5 @@ -import { contains, eventOff, eventOn } from '../utils/dom' - -const eventOptions = { passive: true, capture: false } +import { contains } from '../utils/dom' +import { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff } from '../utils/events' // @vue/component export default { @@ -12,9 +11,19 @@ export default { watch: { listenForClickOut(newValue, oldValue) { if (newValue !== oldValue) { - eventOff(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, eventOptions) + eventOff( + this.clickOutElement, + this.clickOutEventName, + this._clickOutHandler, + EVENT_OPTIONS_NO_CAPTURE + ) if (newValue) { - eventOn(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, eventOptions) + eventOn( + this.clickOutElement, + this.clickOutEventName, + this._clickOutHandler, + EVENT_OPTIONS_NO_CAPTURE + ) } } } @@ -32,11 +41,21 @@ export default { this.clickOutEventName = 'click' } if (this.listenForClickOut) { - eventOn(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, eventOptions) + eventOn( + this.clickOutElement, + this.clickOutEventName, + this._clickOutHandler, + EVENT_OPTIONS_NO_CAPTURE + ) } }, beforeDestroy() /* istanbul ignore next */ { - eventOff(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, eventOptions) + eventOff( + this.clickOutElement, + this.clickOutEventName, + this._clickOutHandler, + EVENT_OPTIONS_NO_CAPTURE + ) }, methods: { isClickOut(evt) { diff --git a/src/mixins/click-out.spec.js b/src/mixins/click-out.spec.js index 2600db16550..2945cf5b983 100644 --- a/src/mixins/click-out.spec.js +++ b/src/mixins/click-out.spec.js @@ -13,12 +13,12 @@ describe('utils/click-out', () => { this.listenForClickOut = true }, methods: { - clickOutHandler(evt) { + clickOutHandler() { count++ } }, render(h) { - return h('div', {}, [h('button', {}, 'button')]) + return h('div', [h('button', 'button')]) } }) diff --git a/src/mixins/focus-in.js b/src/mixins/focus-in.js index 94b84b75c31..f8b9a41d6c0 100644 --- a/src/mixins/focus-in.js +++ b/src/mixins/focus-in.js @@ -1,6 +1,4 @@ -import { eventOff, eventOn } from '../utils/dom' - -const eventOptions = { passive: true, capture: false } +import { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff } from '../utils/events' // @vue/component export default { @@ -12,9 +10,9 @@ export default { watch: { listenForFocusIn(newValue, oldValue) { if (newValue !== oldValue) { - eventOff(this.focusInElement, 'focusin', this._focusInHandler, eventOptions) + eventOff(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE) if (newValue) { - eventOn(this.focusInElement, 'focusin', this._focusInHandler, eventOptions) + eventOn(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE) } } } @@ -28,11 +26,11 @@ export default { this.focusInElement = document } if (this.listenForFocusIn) { - eventOn(this.focusInElement, 'focusin', this._focusInHandler, eventOptions) + eventOn(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE) } }, beforeDestroy() /* istanbul ignore next */ { - eventOff(this.focusInElement, 'focusin', this._focusInHandler, eventOptions) + eventOff(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE) }, methods: { _focusInHandler(evt) { diff --git a/src/mixins/focus-in.spec.js b/src/mixins/focus-in.spec.js index 63975c08193..d2bf5bcf7cf 100644 --- a/src/mixins/focus-in.spec.js +++ b/src/mixins/focus-in.spec.js @@ -13,12 +13,12 @@ describe('utils/focus-in', () => { this.listenForFocusIn = true }, methods: { - focusInHandler(evt) { + focusInHandler() { count++ } }, render(h) { - return h('div', {}, [h('button', {}, 'button')]) + return h('div', [h('button', 'button')]) } }) diff --git a/src/mixins/form-radio-check-group.js b/src/mixins/form-radio-check-group.js index c1e41ee460e..4d79d68e171 100644 --- a/src/mixins/form-radio-check-group.js +++ b/src/mixins/form-radio-check-group.js @@ -67,10 +67,10 @@ export default { } }, watch: { - checked(newVal, oldVal) { + checked(newVal) { this.localChecked = newVal }, - localChecked(newVal, oldVal) { + localChecked(newVal) { this.$emit('input', newVal) } }, diff --git a/src/mixins/form-radio-check.js b/src/mixins/form-radio-check.js index 914a83d6ceb..1704f00f332 100644 --- a/src/mixins/form-radio-check.js +++ b/src/mixins/form-radio-check.js @@ -143,7 +143,7 @@ export default { } }, watch: { - checked(newVal, oldVal) { + checked(newVal) { this.computedLocalChecked = newVal } }, diff --git a/src/mixins/listen-on-document.js b/src/mixins/listen-on-document.js index b3d930e0b24..264ea300d79 100644 --- a/src/mixins/listen-on-document.js +++ b/src/mixins/listen-on-document.js @@ -1,11 +1,9 @@ import { arrayIncludes } from '../utils/array' -import { eventOff, eventOn } from '../utils/dom' import { isBrowser } from '../utils/env' +import { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff } from '../utils/events' import { isString, isFunction } from '../utils/inspect' import { keys } from '../utils/object' -const eventOptions = { passive: true, capture: false } - const PROP = '$_bv_documentHandlers_' // @vue/component @@ -30,7 +28,7 @@ export default { // Remove all registered event handlers keys(items).forEach(evtName => { const handlers = items[evtName] || [] - handlers.forEach(handler => eventOff(document, evtName, handler, eventOptions)) + handlers.forEach(handler => eventOff(document, evtName, handler, EVENT_OPTIONS_NO_CAPTURE)) }) }) }, @@ -43,13 +41,13 @@ export default { this[PROP][evtName] = this[PROP][evtName] || [] if (!arrayIncludes(this[PROP][evtName], handler)) { this[PROP][evtName].push(handler) - eventOn(document, evtName, handler, eventOptions) + eventOn(document, evtName, handler, EVENT_OPTIONS_NO_CAPTURE) } } }, listenOffDocument(evtName, handler) { if (this[PROP] && isString(evtName) && isFunction(handler)) { - eventOff(document, evtName, handler, eventOptions) + eventOff(document, evtName, handler, EVENT_OPTIONS_NO_CAPTURE) this[PROP][evtName] = (this[PROP][evtName] || []).filter(h => h !== handler) } } diff --git a/src/mixins/listen-on-document.spec.js b/src/mixins/listen-on-document.spec.js index c5400f7dd14..8a9be83b9c8 100644 --- a/src/mixins/listen-on-document.spec.js +++ b/src/mixins/listen-on-document.spec.js @@ -23,14 +23,14 @@ describe('mixins/listen-on-document', () => { this.listenOnDocument('click', spyClick2) }, watch: { - offClickOne(newVal, oldVal) { + offClickOne(newVal) { if (newVal) { this.listenOffDocument('click', spyClick1) } } }, render(h) { - return h('div', {}, this.$slots.default) + return h('div', this.$slots.default) } }) @@ -50,8 +50,8 @@ describe('mixins/listen-on-document', () => { const props = { offClickOne: this.offClickOne } - return h('div', {}, [ - h('span', {}, ''), + return h('div', [ + h('span', ''), h('input', { type: 'text' }), this.destroy ? h() : h(TestComponent, { props }, 'test-component') ]) diff --git a/src/mixins/listen-on-root.spec.js b/src/mixins/listen-on-root.spec.js index acd4ce60197..f21236d5f08 100644 --- a/src/mixins/listen-on-root.spec.js +++ b/src/mixins/listen-on-root.spec.js @@ -14,7 +14,7 @@ describe('mixins/listen-on-root', () => { this.listenOnRootOnce('root-once', spyOnce) }, render(h) { - return h('div', {}, this.$slots.default) + return h('div', this.$slots.default) } }) @@ -27,7 +27,7 @@ describe('mixins/listen-on-root', () => { } }, render(h) { - return h('div', {}, [this.destroy ? h() : h(TestComponent, {}, 'test-component')]) + return h('div', [this.destroy ? h() : h(TestComponent, 'test-component')]) } }) diff --git a/src/mixins/listen-on-window.js b/src/mixins/listen-on-window.js index 10ea6876b30..030ea58ca3e 100644 --- a/src/mixins/listen-on-window.js +++ b/src/mixins/listen-on-window.js @@ -1,11 +1,9 @@ import { arrayIncludes } from '../utils/array' -import { eventOff, eventOn } from '../utils/dom' import { isBrowser } from '../utils/env' +import { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff } from '../utils/events' import { isString, isFunction } from '../utils/inspect' import { keys } from '../utils/object' -const eventOptions = { passive: true, capture: false } - const PROP = '$_bv_windowHandlers_' // @vue/component @@ -26,7 +24,7 @@ export default { // Remove all registered event handlers keys(items).forEach(evtName => { const handlers = items[evtName] || [] - handlers.forEach(handler => eventOff(window, evtName, handler, eventOptions)) + handlers.forEach(handler => eventOff(window, evtName, handler, EVENT_OPTIONS_NO_CAPTURE)) }) } }, @@ -39,13 +37,13 @@ export default { this[PROP][evtName] = this[PROP][evtName] || [] if (!arrayIncludes(this[PROP][evtName], handler)) { this[PROP][evtName].push(handler) - eventOn(window, evtName, handler, eventOptions) + eventOn(window, evtName, handler, EVENT_OPTIONS_NO_CAPTURE) } } }, listenOffWindow(evtName, handler) { if (isBrowser && this[PROP] && isString(evtName) && isFunction(handler)) { - eventOff(window, evtName, handler, eventOptions) + eventOff(window, evtName, handler, EVENT_OPTIONS_NO_CAPTURE) this[PROP][evtName] = (this[PROP][evtName] || []).filter(h => h !== handler) } } diff --git a/src/mixins/listen-on-window.spec.js b/src/mixins/listen-on-window.spec.js index d4f10b36dfc..13656e6fcd8 100644 --- a/src/mixins/listen-on-window.spec.js +++ b/src/mixins/listen-on-window.spec.js @@ -23,14 +23,14 @@ describe('mixins/listen-on-window', () => { this.listenOnWindow('resize', spyResize2) }, watch: { - offResizeOne(newVal, oldVal) { + offResizeOne(newVal) { if (newVal) { this.listenOffWindow('resize', spyResize1) } } }, render(h) { - return h('div', {}, this.$slots.default) + return h('div', this.$slots.default) } }) @@ -50,7 +50,7 @@ describe('mixins/listen-on-window', () => { const props = { offResizeOne: this.offResizeOne } - return h('div', {}, [this.destroy ? h() : h(TestComponent, { props }, 'test-component')]) + return h('div', [this.destroy ? h() : h(TestComponent, { props }, 'test-component')]) } }) diff --git a/src/utils/bv-hover-swap.js b/src/utils/bv-hover-swap.js index b605f17d541..27308f99f69 100644 --- a/src/utils/bv-hover-swap.js +++ b/src/utils/bv-hover-swap.js @@ -1,9 +1,5 @@ import Vue from './vue' -import { eventOn, eventOff } from './dom' - -// --- Constants --- - -const EVENT_OPTIONS = { passive: true } +import { EVENT_OPTIONS_PASSIVE, eventOnOff } from './events' // @vue/component export const BVHoverSwap = /*#__PURE__*/ Vue.extend({ @@ -49,9 +45,8 @@ export const BVHoverSwap = /*#__PURE__*/ Vue.extend({ this.listen(false) this.$_hoverEl = el } - const method = on ? eventOn : eventOff - method(this.$_hoverEl, 'mouseenter', this.handleHover, EVENT_OPTIONS) - method(this.$_hoverEl, 'mouseleave', this.handleHover, EVENT_OPTIONS) + eventOnOff(on, this.$_hoverEl, 'mouseenter', this.handleHover, EVENT_OPTIONS_PASSIVE) + eventOnOff(on, this.$_hoverEl, 'mouseleave', this.handleHover, EVENT_OPTIONS_PASSIVE) }, handleHover(evt) { this.isHovered = evt.type === 'mouseenter' diff --git a/src/utils/bv-hover-swap.spec.js b/src/utils/bv-hover-swap.spec.js index 484c2554637..253821460b5 100644 --- a/src/utils/bv-hover-swap.spec.js +++ b/src/utils/bv-hover-swap.spec.js @@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils' import { waitNT } from '../../tests/utils' import { BVHoverSwap } from './bv-hover-swap' -describe('utils/bv-hoverswap', () => { +describe('utils/bv-hover-swap', () => { it('works', async () => { const wrapper = mount(BVHoverSwap, { slots: { @@ -36,7 +36,7 @@ describe('utils/bv-hoverswap', () => { props: { parent: { type: Boolean, - defaut: false + default: false } }, methods: { diff --git a/src/utils/bv-transition.js b/src/utils/bv-transition.js index b74e2d74f2a..e748e0c9ab9 100644 --- a/src/utils/bv-transition.js +++ b/src/utils/bv-transition.js @@ -51,7 +51,7 @@ export const BVTransition = /*#__PURE__*/ Vue.extend({ default: null } }, - render(h, { children, data, listeners, props }) { + render(h, { children, data, props }) { let transProps = props.transProps if (!isPlainObject(transProps)) { transProps = props.noFade ? NO_FADE_PROPS : FADE_PROPS diff --git a/src/utils/dom.js b/src/utils/dom.js index 3145ec61503..4e7f72362f0 100644 --- a/src/utils/dom.js +++ b/src/utils/dom.js @@ -1,6 +1,6 @@ import { from as arrayFrom } from './array' -import { hasWindowSupport, hasDocumentSupport, hasPassiveEventSupport } from './env' -import { isFunction, isNull, isObject } from '../utils/inspect' +import { hasWindowSupport, hasDocumentSupport } from './env' +import { isFunction, isNull } from '../utils/inspect' // --- Constants --- @@ -48,32 +48,6 @@ export const MutationObs = // --- Utils --- -// Normalize event options based on support of passive option -// Exported only for testing purposes -export const parseEventOptions = options => { - /* istanbul ignore else: can't test in JSDOM, as it supports passive */ - if (hasPassiveEventSupport) { - return isObject(options) ? options : { useCapture: !!options || false } - } else { - // Need to translate to actual Boolean value - return !!(isObject(options) ? options.useCapture : options) - } -} - -// Attach an event listener to an element -export const eventOn = (el, evtName, handler, options) => { - if (el && el.addEventListener) { - el.addEventListener(evtName, handler, parseEventOptions(options)) - } -} - -// Remove an event listener from an element -export const eventOff = (el, evtName, handler, options) => { - if (el && el.removeEventListener) { - el.removeEventListener(evtName, handler, parseEventOptions(options)) - } -} - // Remove a node from DOM export const removeNode = el => el && el.parentNode && el.parentNode.removeChild(el) diff --git a/src/utils/dom.spec.js b/src/utils/dom.spec.js index c697a527215..1dfdda22fc6 100644 --- a/src/utils/dom.spec.js +++ b/src/utils/dom.spec.js @@ -10,12 +10,10 @@ import { selectAll, hasAttr, getAttr, - hasClass, - parseEventOptions + hasClass } from './dom' -import { hasPassiveEventSupport } from './env' -const template1 = ` +const template = `
@@ -28,9 +26,7 @@ const template1 = `
` -const App = Vue.extend({ - template: template1 -}) +const App = Vue.extend({ template }) describe('utils/dom', () => { it('isElement works', async () => { @@ -73,7 +69,7 @@ describe('utils/dom', () => { expect($span.exists()).toBe(true) expect(hasClass($span.element, 'barspan')).toBe(true) expect(hasClass($span.element, 'foobar')).toBe(true) - expect(hasClass($span.element, 'fizzlerocks')).toBe(false) + expect(hasClass($span.element, 'fizzle-rocks')).toBe(false) expect(hasClass(null, 'foobar')).toBe(false) wrapper.destroy() @@ -119,7 +115,7 @@ describe('utils/dom', () => { expect($baz.exists()).toBe(true) expect(closest('div.baz', $btns.at(0).element)).toBeDefined() expect(closest('div.baz', $btns.at(0).element)).toBe($baz.element) - expect(closest('div.nothere', $btns.at(0).element)).toBe(null) + expect(closest('div.not-here', $btns.at(0).element)).toBe(null) expect(closest('div.baz', $baz.element)).toBe(null) expect(closest('div.baz', $baz.element, true)).toBe($baz.element) @@ -207,15 +203,15 @@ describe('utils/dom', () => { // With root element specified expect(select('button', wrapper.element)).toBe($btns.at(0).element) expect(select('button#button3', wrapper.element)).toBe($btns.at(2).element) - expect(select('span.nothere', wrapper.element)).toBe(null) + expect(select('span.not-here', wrapper.element)).toBe(null) - // Note: It appears that vue-test-utils is not detaching previous app instances - // and elements once the test is complete! + // Note: It appears that `vue-test-utils` is not detaching previous + // app instances and elements once the test is complete! expect(select('button')).not.toBe(null) expect(select('button')).toBe($btns.at(0).element) expect(select('button#button3')).not.toBe(null) expect(select('button#button3')).toBe($btns.at(2).element) - expect(select('span.nothere')).toBe(null) + expect(select('span.not-here')).toBe(null) wrapper.destroy() }) @@ -246,8 +242,8 @@ describe('utils/dom', () => { expect(selectAll('div.baz button', wrapper.element)[2]).toBe($btns.at(2).element) // Without root element specified (assumes document as root) - // Note: It appears that vue-test-utils is not detaching previous app instances - // and elements once the test is complete! + // Note: It appears that `vue-test-utils` is not detaching previous + // app instances and elements once the test is complete! expect(Array.isArray(selectAll('button'))).toBe(true) expect(selectAll('button')).not.toEqual([]) expect(selectAll('button').length).toBe(3) @@ -266,55 +262,4 @@ describe('utils/dom', () => { wrapper.destroy() }) - - it('event options parsing works', async () => { - // JSDOM probably does not support passive mode - if (hasPassiveEventSupport) { - // Converts boolean to object - expect(parseEventOptions(true)).toEqual({ useCapture: true }) - expect(parseEventOptions(false)).toEqual({ useCapture: false }) - expect(parseEventOptions()).toEqual({ useCapture: false }) - - // Parses object correctly (returns as-is) - expect(parseEventOptions({ useCapture: false })).toEqual({ useCapture: false }) - expect(parseEventOptions({ useCapture: true })).toEqual({ useCapture: true }) - expect(parseEventOptions({})).toEqual({}) - expect( - parseEventOptions({ - useCapture: false, - foobar: true - }) - ).toEqual({ useCapture: false, foobar: true }) - expect( - parseEventOptions({ - useCapture: true, - foobar: false - }) - ).toEqual({ useCapture: true, foobar: false }) - } else { - // Converts non object to boolean - expect(parseEventOptions(true)).toEqual(true) - expect(parseEventOptions(false)).toEqual(false) - expect(parseEventOptions()).toEqual(false) - expect(parseEventOptions(null)).toEqual(false) - // Converts object to boolean - expect(parseEventOptions({ useCapture: false })).toEqual(false) - expect(parseEventOptions({ useCapture: true })).toEqual(true) - expect(parseEventOptions({})).toEqual(false) - expect( - parseEventOptions({ - useCapture: false, - foobar: true - }) - ).toEqual(false) - expect( - parseEventOptions({ - useCapture: true, - foobar: true - }) - ).toEqual(true) - expect(parseEventOptions({ foobar: true })).toEqual(false) - expect(parseEventOptions({ foobar: false })).toEqual(false) - } - }) }) diff --git a/src/utils/events.js b/src/utils/events.js new file mode 100644 index 00000000000..2b489cc10f1 --- /dev/null +++ b/src/utils/events.js @@ -0,0 +1,42 @@ +import { hasPassiveEventSupport } from './env' +import { isObject } from './inspect' + +// --- Constants --- + +export const EVENT_OPTIONS_PASSIVE = { passive: true } +export const EVENT_OPTIONS_NO_CAPTURE = { passive: true, capture: true } + +// --- Utils --- + +// Normalize event options based on support of passive option +// Exported only for testing purposes +export const parseEventOptions = options => { + /* istanbul ignore else: can't test in JSDOM, as it supports passive */ + if (hasPassiveEventSupport) { + return isObject(options) ? options : { capture: !!options || false } + } else { + // Need to translate to actual Boolean value + return !!(isObject(options) ? options.capture : options) + } +} + +// Attach an event listener to an element +export const eventOn = (el, evtName, handler, options) => { + if (el && el.addEventListener) { + el.addEventListener(evtName, handler, parseEventOptions(options)) + } +} + +// Remove an event listener from an element +export const eventOff = (el, evtName, handler, options) => { + if (el && el.removeEventListener) { + el.removeEventListener(evtName, handler, parseEventOptions(options)) + } +} + +// Utility method to add/remove a event listener based on first argument (boolean) +// It passes all other arguments to the `eventOn()` or `eventOff` method +export const eventOnOff = (on, ...args) => { + const method = on ? eventOn : eventOff + method(...args) +} diff --git a/src/utils/events.spec.js b/src/utils/events.spec.js new file mode 100644 index 00000000000..2c94b4c7c85 --- /dev/null +++ b/src/utils/events.spec.js @@ -0,0 +1,41 @@ +import { parseEventOptions } from './events' +import { hasPassiveEventSupport } from './env' + +describe('utils/events', () => { + it('event options parsing works', async () => { + // JSDOM probably does not support passive mode + if (hasPassiveEventSupport) { + // Converts boolean to object + expect(parseEventOptions(true)).toEqual({ capture: true }) + expect(parseEventOptions(false)).toEqual({ capture: false }) + expect(parseEventOptions()).toEqual({ capture: false }) + + // Parses object correctly (returns as-is) + expect(parseEventOptions({ capture: false })).toEqual({ capture: false }) + expect(parseEventOptions({ capture: true })).toEqual({ capture: true }) + expect(parseEventOptions({})).toEqual({}) + expect(parseEventOptions({ capture: false, foobar: true })).toEqual({ + capture: false, + foobar: true + }) + expect(parseEventOptions({ capture: true, foobar: false })).toEqual({ + capture: true, + foobar: false + }) + } else { + // Converts non object to boolean + expect(parseEventOptions(true)).toEqual(true) + expect(parseEventOptions(false)).toEqual(false) + expect(parseEventOptions()).toEqual(false) + expect(parseEventOptions(null)).toEqual(false) + // Converts object to boolean + expect(parseEventOptions({ capture: false })).toEqual(false) + expect(parseEventOptions({ capture: true })).toEqual(true) + expect(parseEventOptions({})).toEqual(false) + expect(parseEventOptions({ capture: false, foobar: true })).toEqual(false) + expect(parseEventOptions({ capture: true, foobar: true })).toEqual(true) + expect(parseEventOptions({ foobar: true })).toEqual(false) + expect(parseEventOptions({ foobar: false })).toEqual(false) + } + }) +}) diff --git a/src/utils/observe-dom.js b/src/utils/observe-dom.js index 57a7b6ca1eb..9824b274362 100644 --- a/src/utils/observe-dom.js +++ b/src/utils/observe-dom.js @@ -5,10 +5,14 @@ import { warnNoMutationObserverSupport } from './warn' * Observe a DOM element changes, falls back to eventListener mode * @param {Element} el The DOM element to observe * @param {Function} callback callback to be called on change - * @param {object} [opts={childList: true, subtree: true}] observe options + * @param {object} [options={childList: true, subtree: true}] observe options * @see http://stackoverflow.com/questions/3219758 */ -const observeDom = (el, callback, opts) => /* istanbul ignore next: difficult to test in JSDOM */ { +const observeDom = ( + el, + callback, + options +) => /* istanbul ignore next: difficult to test in JSDOM */ { // Handle cases where we might be passed a Vue instance el = el ? el.$el || el : null @@ -64,7 +68,7 @@ const observeDom = (el, callback, opts) => /* istanbul ignore next: difficult to }) // Have the observer observe foo for changes in children, etc - obs.observe(el, { childList: true, subtree: true, ...opts }) + obs.observe(el, { childList: true, subtree: true, ...options }) // We return a reference to the observer so that `obs.disconnect()` // can be called if necessary diff --git a/src/utils/plugins.js b/src/utils/plugins.js index 71678a4867e..cabb101a504 100644 --- a/src/utils/plugins.js +++ b/src/utils/plugins.js @@ -55,7 +55,7 @@ export const installFactory = ({ components, directives, plugins } = {}) => { * @returns {function} plugin install function */ export const installFactoryNoConfig = ({ components, directives, plugins } = {}) => { - const install = (Vue, config = {}) => { + const install = Vue => { if (install.installed) { /* istanbul ignore next */ return @@ -77,9 +77,9 @@ export const installFactoryNoConfig = ({ components, directives, plugins } = {}) * @param {object} { components, directives, plugins } * @returns {object} plugin install object */ -export const pluginFactory = (opts = {}, extend = {}) => ({ +export const pluginFactory = (options = {}, extend = {}) => ({ ...extend, - install: installFactory(opts) + install: installFactory(options) }) /** @@ -87,9 +87,9 @@ export const pluginFactory = (opts = {}, extend = {}) => ({ * @param {object} { components, directives, plugins } * @returns {object} plugin install object */ -export const pluginFactoryNoConfig = (opts = {}, extend = {}) => ({ +export const pluginFactoryNoConfig = (options = {}, extend = {}) => ({ ...extend, - install: installFactoryNoConfig(opts) + install: installFactoryNoConfig(options) }) /** diff --git a/src/utils/target.js b/src/utils/target.js index 88ab909869a..a25bff09fe8 100644 --- a/src/utils/target.js +++ b/src/utils/target.js @@ -1,5 +1,5 @@ import { keys } from './object' -import { eventOn, eventOff } from './dom' +import { eventOn, eventOff } from './events' const allListenTypes = { hover: true, click: true, focus: true } diff --git a/src/utils/transporter.spec.js b/src/utils/transporter.spec.js index ebf68c5efa3..5008dd2fbad 100644 --- a/src/utils/transporter.spec.js +++ b/src/utils/transporter.spec.js @@ -8,7 +8,7 @@ describe('utils/transporter component', () => { it('renders in-pace when disabled=true', async () => { const App = localVue.extend({ render(h) { - return h(BTransporterSingle, { props: { disabled: true } }, [h('div', {}, 'content')]) + return h(BTransporterSingle, { props: { disabled: true } }, [h('div', 'content')]) } })