Skip to content

Instantly share code, notes, and snippets.

View Tevinthuku's full-sized avatar
🤓
typing fast

Tev Tevinthuku

🤓
typing fast
View GitHub Profile
@Tevinthuku
Tevinthuku / element.js
Last active August 14, 2019 16:23
our very own createElement
const TEXT_ELEMENT = "TEXT";
/**
* @param {string} type - the node type
* @param {?object} configObject - the props
* @param {?...any} args - the children array
* @returns {object} - to be called by tevreact.render
*/
export function createElement(type, configObject, ...args) {
const props = Object.assign({}, configObject);
@Tevinthuku
Tevinthuku / reconciler.js
Last active August 13, 2019 19:10
Code related to reconciliation
import { updateDomProperties } from "./dom-utils";
import { TEXT_ELEMENT } from "./element";
/**
*
* @param {object} element - vdom representation
* @param {HTMLElement} parentDom - element where children will be appended
*/
export function render(element, parentDom) {
const { type, props } = element;
@Tevinthuku
Tevinthuku / dom-utils.js
Created August 13, 2019 14:05
the dom utility functions.
import { TEXT_ELEMENT } from "./element";
/**
* @param {HTMLElement} dom - the html element where props get applied to
* @param {object} props - consists of both attributes and event listeners.
*/
export function updateDomProperties(dom, props) {
const isListener = name => name.startsWith("on");
Object.keys(props)
.filter(isListener)
@Tevinthuku
Tevinthuku / index.html
Last active August 13, 2019 14:35
A basic demo using our react clone in action.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Didact</title>
</head>
<body>
<div id="app"></div>
@Tevinthuku
Tevinthuku / tevreact.js
Created August 13, 2019 14:40
the main file upon which all functions will be exported to
import { render } from "./reconciler";
import { createElement } from "./element";
export { createElement, render };
export default {
render,
createElement
};
@Tevinthuku
Tevinthuku / index.html
Last active August 13, 2019 18:20
Duplicate call to render
<script type="text/jsx">
/** @jsx tevreact.createElement */
/** In the comment above we are telling babel which function it should
use the default is React.createElement and we want to use
our own createElement function*/
const appElement = (
<div>
<h1>Hello Tev, Have you watched John Wick</h1>
</div>
)
@Tevinthuku
Tevinthuku / instance.js
Created August 13, 2019 18:48
The structure of an instance
const instance = {
dom: HTMLElement, // the rendered dom element
element: {type: String, props: object},
childInstances: Array<instance> // array of child instances
}
@Tevinthuku
Tevinthuku / reconciler.js
Last active August 14, 2019 16:34
reconciliation happenning
import { updateDomProperties } from "./dom-utils";
import { TEXT_ELEMENT } from "./element";
let rootInstance = null; // will keep the reference to the instance rendered on the dom
export function render(element, parentDom) {
const prevInstance = rootInstance;
const nextInstance = reconcile(parentDom, prevInstance, element);
rootInstance = nextInstance;
}
export 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]);
function reconcile(parentDom, instance, element) {
/** code... */
else if (instance.element.type === element.type) {
// perform props update here
updateDomProperties(instance.dom, instance.element.props, element.props);
instance.childInstances = reconcileChildren(instance, element);
instance.element = element;
return instance;
}
/** code... */