Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: component destroy handling on parent destroy (closes #5747) #5749

Merged
merged 1 commit into from Sep 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/components/modal/helpers/bv-modal.js
Expand Up @@ -2,6 +2,7 @@
import { BModal, props as modalProps } from '../modal'
import { concat } from '../../../utils/array'
import { getComponentConfig } from '../../../utils/config'
import { requestAF } from '../../../utils/dom'
import { isUndefined, isFunction } from '../../../utils/inspect'
import {
assign,
Expand Down Expand Up @@ -69,10 +70,11 @@ const plugin = Vue => {
mounted() {
// Self destruct handler
const handleDestroy = () => {
const self = this
this.$nextTick(() => {
// In a `setTimeout()` to release control back to application
setTimeout(() => self.$destroy(), 0)
// In a `requestAF()` to release control back to application
requestAF(() => {
this.$destroy()
})
})
}
// Self destruct if parent destroyed
Expand Down
13 changes: 6 additions & 7 deletions src/components/toast/helpers/bv-toast.js
Expand Up @@ -63,18 +63,17 @@ const plugin = Vue => {
}
},
mounted() {
const self = this
// Self destruct handler
const handleDestroy = () => {
// Ensure the toast has been force hidden
self.localShow = false
self.doRender = false
self.$nextTick(() => {
self.$nextTick(() => {
this.localShow = false
this.doRender = false
this.$nextTick(() => {
this.$nextTick(() => {
// In a `requestAF()` to release control back to application
// and to allow the portal-target time to remove the content
requestAF(() => {
self.$destroy()
this.$destroy()
})
})
})
Expand All @@ -86,7 +85,7 @@ const plugin = Vue => {
// Self destruct when toaster is destroyed
this.listenOnRoot('bv::toaster::destroyed', toaster => {
/* istanbul ignore next: hard to test */
if (toaster === self.toaster) {
if (toaster === this.toaster) {
handleDestroy()
}
})
Expand Down
21 changes: 14 additions & 7 deletions src/components/tooltip/helpers/bv-popper.js
Expand Up @@ -7,7 +7,7 @@

import Vue from '../../../utils/vue'
import Popper from 'popper.js'
import { getCS, select } from '../../../utils/dom'
import { getCS, requestAF, select } from '../../../utils/dom'
import { toFloat } from '../../../utils/number'
import { HTMLElement, SVGElement } from '../../../utils/safe-types'
import { BVTransition } from '../../../utils/bv-transition'
Expand Down Expand Up @@ -139,12 +139,19 @@ export const BVPopper = /*#__PURE__*/ Vue.extend({
this.$on('show', el => {
this.popperCreate(el)
})
// Self destruct once hidden
this.$on('hidden', () => {
this.$nextTick(this.$destroy)
})
// If parent is destroyed, ensure we are destroyed
this.$parent.$once('hook:destroyed', this.$destroy)
// Self destruct handler
const handleDestroy = () => {
this.$nextTick(() => {
// In a `requestAF()` to release control back to application
requestAF(() => {
this.$destroy()
})
})
}
// Self destruct if parent destroyed
this.$parent.$once('hook:destroyed', handleDestroy)
// Self destruct after hidden
this.$once('hidden', handleDestroy)
},
beforeMount() {
// Ensure that the attachment position is correct before mounting
Expand Down
10 changes: 9 additions & 1 deletion src/components/tooltip/helpers/bv-tooltip.js
Expand Up @@ -21,6 +21,7 @@ import {
isElement,
isVisible,
removeAttr,
requestAF,
select,
setAttr
} from '../../../utils/dom'
Expand Down Expand Up @@ -228,7 +229,14 @@ export const BVTooltip = /*#__PURE__*/ Vue.extend({

// Destroy ourselves when the parent is destroyed
if (this.$parent) {
this.$parent.$once('hook:beforeDestroy', this.$destroy)
this.$parent.$once('hook:beforeDestroy', () => {
this.$nextTick(() => {
// In a `requestAF()` to release control back to application
requestAF(() => {
this.$destroy()
})
})
})
}

this.$nextTick(() => {
Expand Down