Avoid error when Panel.destroy is called in a blur listener

This commit is contained in:
Max Brunsfeld
2017-04-10 17:43:52 -07:00
parent 1c6c38e8a8
commit ffff034076
2 changed files with 32 additions and 8 deletions

View File

@@ -5,6 +5,7 @@ describe('Panel', () => {
getElement () {
if (!this.element) {
this.element = document.createElement('div')
this.element.tabIndex = -1
this.element.className = 'test-root'
}
return this.element
@@ -18,15 +19,35 @@ describe('Panel', () => {
expect(element.firstChild).toBe(panel.getItem().getElement())
})
it('removes the element when the panel is destroyed', () => {
const panel = new Panel({item: new TestPanelItem()}, atom.views)
const element = panel.getElement()
const jasmineContent = document.getElementById('jasmine-content')
jasmineContent.appendChild(element)
describe('destroying the panel', () => {
it('removes the element when the panel is destroyed', () => {
const panel = new Panel({item: new TestPanelItem()}, atom.views)
const element = panel.getElement()
const jasmineContent = document.getElementById('jasmine-content')
jasmineContent.appendChild(element)
expect(element.parentNode).toBe(jasmineContent)
panel.destroy()
expect(element.parentNode).not.toBe(jasmineContent)
expect(element.parentNode).toBe(jasmineContent)
panel.destroy()
expect(element.parentNode).not.toBe(jasmineContent)
})
it('does not try to remove the element twice', () => {
const item = new TestPanelItem()
const panel = new Panel({item}, atom.views)
const element = panel.getElement()
const jasmineContent = document.getElementById('jasmine-content')
jasmineContent.appendChild(element)
item.getElement().focus()
expect(item.getElement()).toHaveFocus()
// Avoid this error:
// NotFoundError: Failed to execute 'remove' on 'Element':
// The node to be removed is no longer a child of this node.
// Perhaps it was moved in a 'blur' event handler?
item.getElement().addEventListener('blur', () => panel.destroy())
panel.destroy()
})
})
describe('changing panel visibility', () => {

View File

@@ -14,6 +14,7 @@ class Panel {
*/
constructor ({item, visible, priority, className}, viewRegistry) {
this.destroyed = false
this.item = item
this.visible = visible
this.priority = priority
@@ -26,6 +27,8 @@ class Panel {
// Public: Destroy and remove this panel from the UI.
destroy () {
if (this.destroyed) return
this.destroyed = true
this.hide()
if (this.element) this.element.remove()
this.emitter.emit('did-destroy', this)