Skip to content

Instantly share code, notes, and snippets.

@pawndev
Forked from pomber/render.js
Created May 7, 2017 18:17
Show Gist options
  • Save pawndev/d0160573564bc42fed7eca54e39c9943 to your computer and use it in GitHub Desktop.
Save pawndev/d0160573564bc42fed7eca54e39c9943 to your computer and use it in GitHub Desktop.
function instantiate(element) {
const { type, props } = element;
// Create DOM element
const isTextElement = type === "TEXT ELEMENT";
const dom = isTextElement
? document.createTextNode("")
: document.createElement(type);
updateDomProperties(dom, [], props);
// Instantiate and append children
const childElements = props.children || [];
const childInstances = childElements.map(instantiate);
const childDoms = childInstances.map(childInstance => childInstance.dom);
childDoms.forEach(childDom => dom.appendChild(childDom));
const instance = { dom, element, childInstances };
return instance;
}
function updateDomProperties(dom, prevProps, nextProps) {
const isEvent = name => name.startsWith("on");
const isAttribute = name => !isEvent(name) && name != "children";
// Remove event listeners
Object.keys(prevProps).filter(isEvent).forEach(name => {
const eventType = name.toLowerCase().substring(2);
dom.removeEventListener(eventType, prevProps[name]);
});
// Remove attributes
Object.keys(prevProps).filter(isAttribute).forEach(name => {
dom[name] = null;
});
// Set attributes
Object.keys(nextProps).filter(isAttribute).forEach(name => {
dom[name] = nextProps[name];
});
// Add event listeners
Object.keys(nextProps).filter(isEvent).forEach(name => {
const eventType = name.toLowerCase().substring(2);
dom.addEventListener(eventType, nextProps[name]);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment