rgoussu@goussu: ~/library/frontend/exercises
~/library/frontend/exercises cat toy-browser-engine-subject.md

Toy browser engine — subject

# The stage-by-stage assignment for the toy browser — what to build and how to verify each stage, from raw sockets to a scripted, interactive browser — with the book keeping the prose.

Subjectsaved 2026-08-08source #exercise#frontend#browser#rendering#internals#python#subject

Brief

You are building a web browser in Python — small, slow, incomplete, and real. Given a URL, your program fetches the page, parses its HTML and CSS, computes a layout, paints it into a window, and eventually runs its JavaScript. Web Browser Engineering (Panchekha & Harrelson) is the guide; this subject states what each stage must deliver and how to prove it, so the book keeps the prose and you keep the checklist.

Instructions

Work the stages in order; each leaves a browser that runs.

Stage 1 — URL to pixels

  • Parse a URL into scheme/host/port/path yourself. Open a TCP socket, wrap it in TLS for https, send an HTTP/1.1 GET with Host, and split the response into status line, headers, body.
  • Strip tags naively and draw the text in a desktop window (Tkinter canvas), wrapping at the window edge, with working scroll (keys and/or wheel).

Stage 2 — Trees

  • HTML lexer/parser: tokenize into tags and text, then build a DOM tree. Handle attributes, comments, and the malformed-markup reality: implicit tags and unclosed elements must not crash the parse.
  • Layout tree: build a tree of layout objects mirroring the DOM's block structure; compute each box's x, y, width, height — block layout stacking vertically, text laid out into lines within blocks. Painting now walks the layout tree via a display list, not the token stream.

Stage 3 — Style

  • Parse CSS (selectors + declarations) from both the browser default stylesheet and linked/author sheets.
  • Implement selector matching, specificity-ordered cascade, and inheritance for inheritable properties; resolve a computed style per DOM node and drive layout/paint from it (<b> bolds because a rule says so, not a hardcoded tag check).

Stage 4 — Browser chrome

  • Draw chrome around the page: an address bar you can type a URL into, and back navigation over a history stack.
  • Make links clickable: map a click's coordinates back through the layout tree to the element, follow the href.
  • Forms: input fields you can focus and type into, submit buttons that build and send an HTTP POST request body.

Stage 5 — JavaScript

  • Embed a JS engine (DukPy), expose DOM bindings (document.querySelectorAll, attribute/content access, basic mutation) as your registered functions bridging into Python.
  • Run inline and linked scripts; wire event handlers (click, keydown, form submit with preventDefault) so a page's script can react to and cancel user actions — the single-threaded event loop, seen from the implementer's side.

Constraints

  • Python throughout; standard library plus Tkinter and (for stage 5) DukPy — no requests, no HTML/CSS parsing libraries, no layout engine imports.
  • Write every line yourself; the book's code is reference, not a paste source.
  • Keep each stage's browser runnable end to end — no "it will work again after stage N+1".

Acceptance

Mapped one-to-one onto the exercise's milestones:

  1. Bytes on screenpython browser.py https://example.org/ opens a window showing the page text; a page taller than the window scrolls; both http and https fetch.
  2. Trees — a nested test page renders with correct block positions; a deliberately malformed page (unclosed <p>, stray </b>) still parses to a sensible DOM; dumping the layout tree shows computed sizes/positions for every box.
  3. Style — an author stylesheet changes rendering without code changes; a more-specific selector beats a less-specific one; a child inherits color from its parent; default styling comes from the browser stylesheet, not tag-name conditionals.
  4. A real browser — you can type a URL in the address bar, click a link, go back, and submit a form whose POST reaches the server (verify against a local echo server).
  5. JavaScript — a page whose script mutates the DOM re-renders to show the change; a click handler fires; a form's submit handler can cancel submission.

Related