-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
basic string child node render and update!
- Loading branch information
Showing
2 changed files
with
158 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,98 +1,122 @@ | ||
import { test } from 'vitest'; | ||
import { describe, test } from 'vitest'; | ||
import { compose } from '../compose/compose.js'; | ||
import { makeRenderer, getBoundElements } from './renderer.js'; | ||
import { makeRenderer, makeTemplate, Controller, Updater, makeStringRenderer } from './renderer.js'; | ||
|
||
// template generated artifacts | ||
const source = makeRenderer('id', `<p data-bind><!--0--></p>`); | ||
const stringSource = makeStringRenderer('id', [`<p data-bind>`, `</p>`]); | ||
|
||
let injectableRoot = null; | ||
function injectRender(dom, callback) { | ||
injectableRoot = dom; | ||
callback(); | ||
injectableRoot = null; | ||
} | ||
|
||
function getBindTargets(r, boundEls) { | ||
function getTargets(r, boundEls) { | ||
return [r.childNodes[0]]; | ||
} | ||
|
||
const makeBind = targets => { | ||
const t0 = targets[0]; | ||
return p0 => { | ||
compose(t0, p0); | ||
}; | ||
}; | ||
|
||
function getStringTargets(r, boundEls) { | ||
return [boundEls[0]]; | ||
} | ||
|
||
const makeStringBind = targets => { | ||
const t0 = targets[0]; | ||
return p0 => { | ||
t0[0] = p0; | ||
}; | ||
}; | ||
function render123(p0) { | ||
const [root, bind] = makeTemplate(source); | ||
const [root, bind] = makeTemplate( | ||
source, | ||
getTargets, | ||
makeBind | ||
); | ||
bind(p0); | ||
return root; | ||
} | ||
function renderString(p0) { | ||
const [root, bind] = makeTemplate( | ||
stringSource, | ||
getStringTargets, | ||
makeStringBind | ||
); | ||
bind(p0); | ||
return root; | ||
} | ||
/* | ||
const NameTag = Controller.for(({ greeting, name }) => { | ||
const Greeting = Controller.for(greeting => <span>{greeting}</span>); | ||
const map = new Map(); | ||
|
||
const makeTemplate = (source) => { | ||
let bind = null; | ||
let root = injectableRoot; | ||
// TODO: test injectable is right template id | ||
|
||
if(root) bind = map.get(root); | ||
if(!bind) { | ||
const result = root | ||
? [root, getBoundElements(root)] | ||
: source(); | ||
root = result[0]; | ||
const nodes = getBindTargets(root, result[1]); | ||
bind = makeBind(nodes); | ||
map.set(root, bind); | ||
} | ||
|
||
return [root, bind]; | ||
}; | ||
return <p> | ||
<Greeting greeting={greeting} /> {name} | ||
</p>; | ||
}); | ||
class Controller { | ||
static for(renderFn) { | ||
return new this(renderFn); | ||
} | ||
constructor(renderFn) { | ||
this.renderFn = renderFn; | ||
} | ||
render(props) { | ||
return this.renderFn(props); | ||
} | ||
update(dom, props) { | ||
injectRender(dom, () => this.renderFn(props)); | ||
} | ||
} | ||
const Hello = Controller.for(name => <p>{name}</p>); | ||
*/ | ||
describe('string render', () => { | ||
const flatRender = node => node.flat().join(''); | ||
test('Controller.for', ({ expect }) => { | ||
const controller = Controller.for(name => renderString(name)); | ||
|
||
class Updater extends Controller { | ||
#dom = null; | ||
render(props) { | ||
return this.#dom = super.render(props); | ||
} | ||
update(props) { | ||
super.update(this.#dom, props); | ||
} | ||
} | ||
let node1 = controller.render('felix'); | ||
let node2 = controller.render('duchess'); | ||
expect(flatRender(node1)).toMatchInlineSnapshot( | ||
`"<p data-bind>felix</p>"` | ||
); | ||
expect(flatRender(node2)).toMatchInlineSnapshot( | ||
`"<p data-bind>duchess</p>"` | ||
); | ||
|
||
test('controller creates or injects', ({ expect }) => { | ||
const controller = Controller.for(name => render123(name)); | ||
controller.update(node1, 'garfield'); | ||
controller.update(node2, 'stimpy'); | ||
expect(flatRender(node1)).toMatchInlineSnapshot( | ||
`"<p data-bind>garfield</p>"` | ||
); | ||
expect(flatRender(node2)).toMatchInlineSnapshot( | ||
`"<p data-bind>stimpy</p>"` | ||
); | ||
}); | ||
|
||
let dom1 = controller.render('felix'); | ||
let dom2 = controller.render('duchess'); | ||
expect(dom1.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">felix<!--1--></p>"`); | ||
expect(dom2.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">duchess<!--1--></p>"`); | ||
test('Updater.for', ({ expect }) => { | ||
const updater = Updater.for(name => renderString(name)); | ||
const node = updater.render('felix'); | ||
expect(flatRender(node)).toMatchInlineSnapshot( | ||
`"<p data-bind>felix</p>"` | ||
); | ||
|
||
updater.update('duchess'); | ||
expect(flatRender(node)).toMatchInlineSnapshot( | ||
`"<p data-bind>duchess</p>"` | ||
); | ||
}); | ||
|
||
controller.update(dom1, 'garfield'); | ||
controller.update(dom2, 'stimpy'); | ||
expect(dom1.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">garfield<!--1--></p>"`); | ||
expect(dom2.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">stimpy<!--1--></p>"`); | ||
}); | ||
describe('dom render', () => { | ||
|
||
test('Controller.for', ({ expect }) => { | ||
const controller = Controller.for(name => render123(name)); | ||
|
||
let node1 = controller.render('felix'); | ||
let node2 = controller.render('duchess'); | ||
expect(node1.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">felix<!--1--></p>"`); | ||
expect(node2.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">duchess<!--1--></p>"`); | ||
|
||
controller.update(node1, 'garfield'); | ||
controller.update(node2, 'stimpy'); | ||
expect(node1.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">garfield<!--1--></p>"`); | ||
expect(node2.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">stimpy<!--1--></p>"`); | ||
}); | ||
|
||
test('Updater.for', ({ expect }) => { | ||
const updater = Updater.for(name => render123(name)); | ||
const node = updater.render('felix'); | ||
expect(node.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">felix<!--1--></p>"`); | ||
|
||
test('update remembers dom', ({ expect }) => { | ||
const updater = Updater.for(name => render123(name)); | ||
const dom = updater.render('felix'); | ||
expect(dom.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">felix<!--1--></p>"`); | ||
updater.update('duchess'); | ||
expect(node.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">duchess<!--1--></p>"`); | ||
}); | ||
|
||
updater.update('duchess'); | ||
expect(dom.outerHTML).toMatchInlineSnapshot(`"<p data-bind="">duchess<!--1--></p>"`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters