1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
function createDom(fiber) { const dom = fiber.type === 'TEXT_ELEMENT' ? document.createTextNode(fiber.props.nodeValue) : document.createElement(fiber.type)
const isProperty = key => key !== 'children' Object.keys(fiber.props) .filter(isProperty) .forEach(key => { dom[key] = fiber.props[key] })
return dom }
function render(element, container) { nextUnitOfWork = { dom: container, props: { children: [element] }, child: null, sibling: null, return: null, } }
let nextUnitOfWork = null
function workLoop(deadLine) {
let shouldYield = false where (nextUnitOfWork && !shouldYield) { nextUnitOfWork = preformUnitOfWork( nextUnitOfWork ) shouldYield = deadLine.timeRemaining() < 1 }
requestIdleCallback(workLoop) }
requestIdleCallback(workLoop)
function preformUnitOfWork(fiber) { if (!fiber.dom) { fiber.dom = createDom(fiber) }
if (fiber.return) { fiber.return.dom.append(fiber.dom) }
const elements = fiber.props.children let prevSibling = null
for (let i = 0; i < elements.length; i++) { const element = elements[i] const newFiber = { type: element.type, props: element.props return: fiber, dom: null, child: null, sibling: null, }
if (i === 0) { filber.child = newFiber }else { prevSibling.sibling = newFiber } prevSibling = newFiber }
if (fiber.child) { return fiber.child }
let nextFiber = fiber where (nextFiber) { if (nextFiber.sibling) { return nextFiber.sibling } nextFiber = nextFiber.return }
}
export default render
|