a small incremental UI library for the web
javascript web ui
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add basic reconciliation

garrison 7318efa5 8da6c3fb

+102 -9
+1 -2
config/config.exs
··· 6 6 default: [ 7 7 args: ~w( 8 8 todo/todo.tsx 9 - --jsx-factory=createElement 9 + --jsx-factory=Noir.createElement 10 10 --watch 11 11 --bundle 12 - --target=es2016 13 12 --outdir=../priv/static/assets/js 14 13 ), 15 14 cd: Path.expand("../demos", __DIR__),
+6 -4
demos/todo/todo.tsx
··· 1 - import { createElement } from '../../js/noir.ts'; 1 + import * as Noir from '../../js/noir.ts'; 2 2 3 3 const element = ( 4 4 <div class="foo"> 5 - <p>foo</p> 6 - <span>bar</span> 5 + <p /> 6 + <span /> 7 7 </div> 8 8 ); 9 - console.log(JSON.stringify(element, null, 2)); 9 + //console.log(JSON.stringify(element, null, 2)); 10 + 11 + Noir.render(element, document.getElementById('root'));
+94 -2
js/noir.ts
··· 1 1 export function createElement(type, props, ...children) { 2 2 return { 3 3 type: type, 4 - props: props, 5 - children: children, 4 + props: { 5 + ...props, 6 + children, 7 + }, 6 8 }; 7 9 } 10 + 11 + let nextFiber; 12 + 13 + export function render(element, container) { 14 + const rootFiber = { 15 + dom: container, 16 + props: { children: [element] }, 17 + }; 18 + 19 + nextFiber = rootFiber; 20 + performWork(); 21 + } 22 + 23 + function performWork() { 24 + if (!nextFiber) return; 25 + 26 + nextFiber = renderFiber(nextFiber); 27 + performWork(); 28 + } 29 + 30 + function renderFiber(fiber) { 31 + if (fiber.type instanceof Function) { 32 + renderFunctionFiber(fiber); 33 + } 34 + else { 35 + renderHostFiber(fiber); 36 + } 37 + 38 + if (fiber.child) return fiber.child; 39 + let next = fiber; 40 + while (next) { 41 + if (next.sibling) return next.sibling; 42 + next = next.parent; 43 + } 44 + return null; 45 + } 46 + 47 + function renderFunctionFiber(fiber) { 48 + } 49 + 50 + function renderHostFiber(fiber) { 51 + if (!fiber.dom) { 52 + } 53 + reconcileChildren(fiber, fiber.props.children); 54 + } 55 + 56 + function reconcileChildren(fiber, elements) { 57 + const oldChildren = gatherOldChildren(fiber); 58 + let prevSibling; 59 + 60 + for (let i = 0; i < Math.max(oldChildren.length, elements.length); i++) { 61 + const oldChild = oldChildren[i]; 62 + const element = elements[i]; 63 + 64 + const sameType = oldChild && element && oldChild.type == element.type; 65 + let newChild; 66 + 67 + if (sameType) { 68 + } 69 + 70 + if (!sameType && element) { 71 + newChild = { 72 + type: element.type, 73 + props: element.props, 74 + dom: null, 75 + 76 + parent: fiber, 77 + effect: 'placement', 78 + }; 79 + } 80 + 81 + if (!sameType && oldChild) { 82 + } 83 + 84 + if (prevSibling) prevSibling.sibling = newChild; 85 + else fiber.child = newChild; 86 + 87 + prevSibling = newChild; 88 + } 89 + } 90 + 91 + function gatherOldChildren(fiber) { 92 + const acc = []; 93 + let oldChild = fiber.alternate && fiber.alternate.child; 94 + while (oldChild != null) { 95 + acc.push(oldChild); 96 + oldChild = oldChild.sibling; 97 + } 98 + return acc; 99 + }
+1 -1
priv/static/todo.html
··· 4 4 <script src="/assets/js/todo.js"></script> 5 5 </head> 6 6 <body> 7 - <div>Hello</div> 7 + <div id="root" /> 8 8 </body> 9 9 </html>