src — foster parenting lab

a.html b.html c.html d.html   fixtures (exact whitespace)
show.js                       browser-side tree dumper
serialize.mjs                 shared serializer — same format as show.js
tokens.mjs                    pre-tokenized input for the tree builder
run.mjs                       print your tree for one case
check.mjs                     diff your tree against the browser
observed/                     where you save the browser's output
foster.js                     ← YOU WRITE THIS

Everything here except foster.js is plumbing. foster.js is the lab.

What foster.js must export

export function buildTree(tokens) {
  // returns the body root:
  // { type: 'element', name: 'body', attrs: {}, children: [...] }
}

Node shapes:

{ type: 'element', name: 'div', attrs: { id: 'x' }, children: [] }
{ type: 'text', data: 'hello' }

Under ~80 lines, no dependencies. Implement only: a stack of open elements, two insertion modes (inBody, inTable), an appropriateInsertionPlace(fosterParenting) function, and the <input type=hidden> exception.

Workflow

node run.mjs a       # see your output
node check.mjs a     # diff against the browser
node check.mjs       # all cases with an observed/ file

Cases a, b, d must pass exactly. Case c is the stretch goal — attempt it only after the others, and read the diff rather than fixing it blindly.

This file becomes mini-browser milestone M2. Keep it.