mirror of
https://github.com/atom/atom.git
synced 2026-01-25 23:08:18 -05:00
90 lines
2.4 KiB
JavaScript
90 lines
2.4 KiB
JavaScript
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()
|
|
}
|
|
|
|
buildElement (tagName, className) {
|
|
const elements = this.freeElementsByTagName.get(tagName)
|
|
let element = elements ? elements.pop() : null
|
|
if (element) {
|
|
for (let dataId in element.dataset) { delete element.dataset[dataId] }
|
|
element.removeAttribute('style')
|
|
if (className) {
|
|
element.className = className
|
|
} else {
|
|
element.removeAttribute('class')
|
|
}
|
|
while (element.firstChild) {
|
|
element.removeChild(element.firstChild)
|
|
}
|
|
this.freedElements.delete(element)
|
|
} else {
|
|
element = document.createElement(tagName)
|
|
if (className) {
|
|
element.className = className
|
|
}
|
|
this.managedElements.add(element)
|
|
}
|
|
return element
|
|
}
|
|
|
|
buildText (textContent) {
|
|
const elements = this.freeElementsByTagName.get('#text')
|
|
let element = elements ? elements.pop() : null
|
|
if (element) {
|
|
element.textContent = textContent
|
|
this.freedElements.delete(element)
|
|
} else {
|
|
element = document.createTextNode(textContent)
|
|
this.managedElements.add(element)
|
|
}
|
|
return element
|
|
}
|
|
|
|
freeElementAndDescendants (element) {
|
|
this.free(element)
|
|
element.remove()
|
|
}
|
|
|
|
freeDescendants (element) {
|
|
while (element.firstChild) {
|
|
this.free(element.firstChild)
|
|
element.removeChild(element.firstChild)
|
|
}
|
|
}
|
|
|
|
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 window.Text ? element.textContent : element.outerHTML
|
|
})
|
|
return
|
|
}
|
|
|
|
const tagName = element.nodeName.toLowerCase()
|
|
let elements = this.freeElementsByTagName.get(tagName)
|
|
if (!elements) {
|
|
elements = []
|
|
this.freeElementsByTagName.set(tagName, elements)
|
|
}
|
|
elements.push(element)
|
|
this.freedElements.add(element)
|
|
|
|
for (let i = element.childNodes.length - 1; i >= 0; i--) {
|
|
const descendant = element.childNodes[i]
|
|
this.free(descendant)
|
|
}
|
|
}
|
|
}
|