diff-dom
Version:
A diff for DOM elements, as client-side JavaScript code. Gets all modifications, insertions and removals between two DOM fragments.
75 lines (73 loc) • 2.8 kB
text/typescript
import { DiffDOMOptionsPartial, elementNodeType, textNodeType } from "../types"
import { checkElementType } from "../helpers"
export function nodeToObj(
aNode: Element,
options: DiffDOMOptionsPartial = { valueDiffing: true },
) {
const objNode: elementNodeType | textNodeType = {
nodeName: aNode.nodeName,
}
if (checkElementType(aNode, "Text", "Comment")) {
;(objNode as unknown as textNodeType).data = (
aNode as unknown as Text | Comment
).data
} else {
if (aNode.attributes && aNode.attributes.length > 0) {
objNode.attributes = {}
const nodeArray = Array.prototype.slice.call(aNode.attributes)
nodeArray.forEach(
(attribute) =>
(objNode.attributes[attribute.name] = attribute.value),
)
}
if (aNode.childNodes && aNode.childNodes.length > 0) {
objNode.childNodes = []
const nodeArray = Array.prototype.slice.call(aNode.childNodes)
nodeArray.forEach((childNode) =>
objNode.childNodes.push(nodeToObj(childNode, options)),
)
}
if (options.valueDiffing) {
if (checkElementType(aNode, "HTMLTextAreaElement")) {
objNode.value = (aNode as HTMLTextAreaElement).value
}
if (
checkElementType(aNode, "HTMLInputElement") &&
["radio", "checkbox"].includes(
(aNode as HTMLInputElement).type.toLowerCase(),
) &&
(aNode as HTMLInputElement).checked !== undefined
) {
objNode.checked = (aNode as HTMLInputElement).checked
} else if (
checkElementType(
aNode,
"HTMLButtonElement",
"HTMLDataElement",
"HTMLInputElement",
"HTMLLIElement",
"HTMLMeterElement",
"HTMLOptionElement",
"HTMLProgressElement",
"HTMLParamElement",
)
) {
objNode.value = (
aNode as
| HTMLButtonElement
| HTMLDataElement
| HTMLInputElement
| HTMLLIElement
| HTMLMeterElement
| HTMLOptionElement
| HTMLProgressElement
| HTMLParamElement
).value
}
if (checkElementType(aNode, "HTMLOptionElement")) {
objNode.selected = (aNode as HTMLOptionElement).selected
}
}
}
return objNode
}