diff --git a/spec/dom-element-pool-spec.js b/spec/dom-element-pool-spec.js
index 52f4d772e..959003ca8 100644
--- a/spec/dom-element-pool-spec.js
+++ b/spec/dom-element-pool-spec.js
@@ -51,29 +51,44 @@ describe('DOMElementPool', function () {
expect(domElementPool.buildElement('div')).not.toBe(div)
})
+ it('does not attempt to free nodes that were not created by the pool', () => {
+ let assertionFailure
+ atom.onDidFailAssertion((error) => assertionFailure = error)
+
+ const foreignDiv = document.createElement('div')
+ const div = domElementPool.buildElement('div')
+ div.appendChild(foreignDiv)
+ domElementPool.freeElementAndDescendants(div)
+ const span = domElementPool.buildElement('span')
+ span.appendChild(foreignDiv)
+ domElementPool.freeElementAndDescendants(span)
+
+ expect(assertionFailure).toBeUndefined()
+ })
+
it('fails an assertion when freeing the same element twice', function () {
- let failure
- atom.onDidFailAssertion((error) => failure = error)
+ let assertionFailure
+ atom.onDidFailAssertion((error) => assertionFailure = error)
const div = domElementPool.buildElement('div')
div.textContent = 'testing'
domElementPool.freeElementAndDescendants(div)
- expect(failure).toBeUndefined()
+ expect(assertionFailure).toBeUndefined()
domElementPool.freeElementAndDescendants(div)
- expect(failure.message).toBe('Assertion failed: The element has already been freed!')
- expect(failure.metadata.content).toBe('
testing
')
+ expect(assertionFailure.message).toBe('Assertion failed: The element has already been freed!')
+ expect(assertionFailure.metadata.content).toBe('testing
')
})
it('fails an assertion when freeing the same text node twice', function () {
- let failure
- atom.onDidFailAssertion((error) => failure = error)
+ let assertionFailure
+ atom.onDidFailAssertion((error) => assertionFailure = error)
const node = domElementPool.buildText('testing')
domElementPool.freeElementAndDescendants(node)
- expect(failure).toBeUndefined()
+ expect(assertionFailure).toBeUndefined()
domElementPool.freeElementAndDescendants(node)
- expect(failure.message).toBe('Assertion failed: The element has already been freed!')
- expect(failure.metadata.content).toBe('testing')
+ expect(assertionFailure.message).toBe('Assertion failed: The element has already been freed!')
+ expect(assertionFailure.metadata.content).toBe('testing')
})
it('throws an error when trying to free an invalid element', function () {
diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js
index 624e0b74f..683a1d247 100644
--- a/src/dom-element-pool.js
+++ b/src/dom-element-pool.js
@@ -1,11 +1,13 @@
module.exports =
class DOMElementPool {
constructor () {
+ this.managedElements = new Set()
this.freeElementsByTagName = new Map()
this.freedElements = new Set()
}
clear () {
+ this.managedElements.clear()
this.freedElements.clear()
this.freeElementsByTagName.clear()
}
@@ -27,6 +29,7 @@ class DOMElementPool {
this.freedElements.delete(element)
} else {
element = document.createElement(tagName)
+ this.managedElements.add(element)
}
return element
}
@@ -39,6 +42,7 @@ class DOMElementPool {
this.freedElements.delete(element)
} else {
element = document.createTextNode(textContent)
+ this.managedElements.add(element)
}
return element
}
@@ -50,6 +54,7 @@ class DOMElementPool {
free (element) {
if (element == null) { throw new Error('The element cannot be null or undefined.') }
+ if (!this.managedElements.has(element)) return
if (this.freedElements.has(element)) {
atom.assert(false, 'The element has already been freed!', {
content: element instanceof Text ? element.textContent : element.outerHTML.toString()