Skip to content

Commit

Permalink
Fix DOM nodes cleanup-on-reuse bug
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleg Klimenko committed Jun 2, 2016
1 parent dbb9463 commit c4d20ba
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/dom/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@ export default class Pool {
}

store (el) {
if (!this._recyclingEnabled) {
if (!this._recyclingEnabled || el._collected || !el.nodeType || el.nodeType !== 1 /* Node.ELEMENT_NODE == 1 */) {
return
}
el._collected = true

if (el && el.parentNode) {
el.parentNode.removeChild(el)
}

if (!el.nodeType || el.nodeType !== 1 /* Node.ELEMENT_NODE == 1 */) {
return
}

let tagName = el.tagName.toLowerCase()
if (!this.storage[tagName]) {
this.storage[tagName] = []
}

// little cleanup
el.className = ''
for (let i = 0; i < el.attributes.length; i++) {
el.removeAttribute(el.attributes[i].name)
}

if (el.childNodes.length > 0) {
for (let i = 0; i < el.childNodes.length; i++) {
// Iterate backwards, because childNodes is live collection
for (let i = el.childNodes.length - 1; i >=0; i--) {
this.store(el.childNodes[i])
}
}
Expand All @@ -45,7 +45,9 @@ export default class Pool {
get (tagName) {
tagName = tagName.toLowerCase()
if (this._recyclingEnabled && this.storage[tagName] && this.storage[tagName].length > 0) {
return this.storage[tagName].pop()
let el = this.storage[tagName].pop()
delete el._collected
return el
}
return createNativeElement(tagName)
}
Expand Down
20 changes: 20 additions & 0 deletions test/dom/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,26 @@ test('storeDomNode', t => {
t.end()
})

test('storeNestedNodes', t => {
let node = document.createElement('div')
for (let i = 0; i < 10; i++) {
node.appendChild(document.createElement('div'))
}
let pool = new Pool()
pool.enableRecycling(true)

pool.store(node)

let childNodesCount = 0;
while (pool._getStorageSizeFor('div') > 0) {
let storedNode = pool.get('div')
childNodesCount += storedNode.childNodes.length
}

t.equal(childNodesCount, 0, 'Stored nested nodes were flattened and do not have children')
t.end()
})

test('getNewDomNode', t => {
let pool = new Pool()
let newNode = pool.get('div')
Expand Down

0 comments on commit c4d20ba

Please sign in to comment.