Last active
August 29, 2015 14:22
-
-
Save fleon/5de37b0fedcbe9409083 to your computer and use it in GitHub Desktop.
DOMFootprint
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Creates a new DOMFootprint for the given HTML node. | |
* @param {Node} element The HTML node to create a footprint for. | |
*/ | |
function DOMFootprint(element) { | |
this.element = element; | |
this.capture(); | |
} | |
DOMFootprint.prototype = { | |
/** | |
* Captures the footprint of the DOM element and its descendants. | |
*/ | |
capture: function () { | |
this.nodeName = this.element.nodeName; | |
this.nodeType = this.element.nodeType; | |
// element node | |
if (this.element.nodeType === 1) { | |
// capture all children and attributes | |
this.children = []; | |
this.attributes = {}; | |
for (var i = 0, il = this.element.childNodes.length; i < il; i++) { | |
this.children[i] = new DOMFootprint(this.element.childNodes[i]); | |
} | |
for (var j = 0, jl = this.element.attributes.length; j < jl; j++) { | |
this.attributes[j] = this.element.attributes[j].name; | |
this.attributes[this.attributes[j]] = this.element.attributes[j].value; | |
this.attributes.length = this.element.attributes.length; | |
} | |
} | |
// text node or comment node | |
else if (this.element.nodeType === 3 || this.element.nodeType === 8) { | |
// capture textContent | |
this.textContent = this.element.textContent; | |
} | |
return this; | |
}, | |
/** | |
* Restores the element to the state of its previously captured footprint. | |
*/ | |
restore: function () { | |
// element node | |
if (this.nodeType === 1) { | |
// remove all existing children | |
while (this.element.childNodes.length) { | |
this.element.removeChild(this.element.childNodes[0]); | |
} | |
// update all attributes | |
var attributesToRemove = []; | |
for (var i = this.element.attributes.length; i--;) { | |
if (this.attributes.hasOwnProperty(this.element.attributes[i].name)) { | |
if (this.element.attributes[i].value === this.attributes[this.attributes[i]]) { | |
continue; | |
} | |
this.element.setAttribute(this.attributes[i], this.attributes[this.attributes[i]]); | |
} else { | |
attributesToRemove.push(this.element.attributes[i].name); | |
} | |
} | |
for (var attribute = attributesToRemove.pop(); attribute;) { | |
this.element.removeAttribute(attribute); | |
} | |
// append and restore the footprints of all old children | |
for (var j = 0, jl = this.children.length; j < jl; j++) { | |
this.element.appendChild(this.children[j].element); | |
this.children[j].restore(); | |
} | |
} | |
// text node or comment node | |
else if (this.element.nodeType === 3 || this.element.nodeType === 8) { | |
this.element.textContent = this.textContent; | |
} | |
return this; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment