Skip to content

Phase 2: Web page rendering #19

@thomasnemer

Description

@thomasnemer

Context

Phase 1 delivers browser infrastructure: window, tabs, bookmarks, networking, headless mode, e2e tests. Phase 2 makes the browser actually render web pages. The goal is a vertical slice where the user navigates to a URL and sees rendered HTML with styled text, colored blocks, and flexbox layouts — plus working JavaScript.

Steps

Step Crate What Parallel?
1 ie-html WHATWG HTML tokenizer (~80 states) Yes (with 3)
2 ie-html WHATWG tree builder (~20 insertion modes) After 1
3 ie-css CSS tokenizer + parser + selectors + cascade Yes (with 1)
4 ie-css Style resolution pipeline (matching + inheritance) After 2+3
5 ie-layout Block + inline layout, positioning After 4
6 ie-render GPU paint pipeline + text rendering + browser chrome After 5, first visual
7 ie-layout Flexbox layout After 5
8 ie-js + ie-wasm JS runtime with DOM bindings, events, wasm interop After 2 (parallel with 6-7)

Step 1: HTML Tokenizer

Crate: ie-html — rewrite tokenizer.rs

  • WHATWG state machine with ~80 states (TokenizerState enum)
  • Iterator-based: impl Iterator<Item = Token> (not batch Vec<Token>)
  • Expand Token enum: StartTag gets attributes: Vec<(String, String)>, Doctype gets name/public_id/system_id/force_quirks
  • Character reference resolution: ~2200 named entities from WHATWG entities.json, codegen via build.rs
  • Parse errors emitted as tracing warnings, never abort
  • Tests: vendor html5lib-tests tokenizer suite (JSON fixtures), conformance harness

Step 2: HTML Tree Builder

Crate: ie-html — rewrite tree_builder.rs

  • ~20 insertion modes (Initial, BeforeHtml, InBody, InTable, etc.)
  • Open element stack, active formatting elements list
  • Adoption agency algorithm
  • Foster parenting, implied end tags
  • <script> pauses tree construction → callback to caller for script execution
  • No quirks mode (always "no-quirks")
  • Tests: vendor html5lib-tests tree construction suite, target >95% pass rate

Step 3: CSS Tokenizer and Parser

Crate: ie-css — new tokenizer.rs, rewrite parser.rs/selector.rs/style.rs

  • CSS Syntax Level 3 tokenizer (iterator-based)
  • Parse rules: qualified rules, @media, @import
  • Selectors: combinators (descendant, child, sibling), pseudo-classes (:hover, :focus, :nth-child(), :not(), :root), attribute selectors, universal selector
  • Specificity computation (specificity.rs)
  • Cascade algorithm (cascade.rs): origin ordering + specificity + source order
  • Expand ComputedStyle to ~40 properties: box model, typography, positioning, flexbox, background, overflow, visibility
  • Extended Value types: all length units, colors (hex, rgb, hsl, named), calc() basic arithmetic
  • User-agent stylesheet (ua.css): WHATWG normative UA stylesheet, embedded as const
  • Tests: targeted unit tests for parsing, selector matching, cascade

Step 4: Style Resolution Pipeline

Crates: ie-css + ie-dom

  • Selector matching engine (matching.rs): matches(selector, node, doc) -> bool
  • Style resolution (resolve.rs): produce ComputedStyle per node
  • Apply UA stylesheet → author stylesheets
  • Inheritance: inherited properties propagate, non-inherited use initial values
  • Value computation: resolve relative units (em, rem, %) top-down
  • Extract <style> contents and <link rel="stylesheet"> during tree building
  • Tests: parse HTML with <style>, resolve styles, assert computed values

Step 5: Block and Inline Layout

Crate: ie-layout — new box_generation.rs, block.rs, inline.rs, positioned.rs

  • Box tree construction from styled DOM (display → box type, anonymous boxes)
  • Block formatting context: vertical stacking, width algorithm, margin collapsing
  • Inline formatting context: line boxes, text measurement via TextMeasure trait, line breaking, text-align
  • Positioned layout: relative, absolute, fixed, stacking contexts
  • TextMeasure trait defined in ie-layout, implemented by ie-render (trait inversion)
  • Tests: hand-crafted styled DOM trees, mock TextMeasure, verify geometry

Step 6: GPU Paint Pipeline + Text + Chrome (first visual)

Crate: ie-render — major expansion

  • Display list: walk layout tree → Vec<PaintCommand> (PaintRect, PaintBorder, PaintText)
  • Rect rendering pipeline: WGSL shader for solid-color quads
  • Text rendering via glyphon (cosmic-text shaping + swash rasterization + wgpu integration)
  • glyphon implements TextMeasure trait for ie-layout
  • Surface management: resize, frame rendering
  • Browser chrome rendering: address bar overlay, tab list — same rect+text pipeline as content
  • Headless rendering: wgpu software backend for CI tests
  • New workspace deps: glyphon, cosmic-text
  • Tests: display list assertions, headless pixel readback

Step 7: Flexbox Layout

Crate: ie-layout — new flex.rs

  • CSS Flexible Box Layout Module Level 1
  • Main/cross axis, flex base sizes, flex-grow/flex-shrink
  • Multi-line: flex-wrap
  • Alignment: justify-content, align-items, align-self
  • gap property
  • Tests: centering, space-between, wrap patterns

Step 8: JavaScript + WebAssembly

Crates: ie-js + ie-wasm (parallel with 6-7)

  • DOM bindings: document.getElementById(), querySelector(), createElement(), appendChild(), etc.
  • Event system: addEventListener(), capture → target → bubble, click/keydown/keyup/DOMContentLoaded/load
  • console.log/warn/error → tracing
  • setTimeout/setInterval → event loop integration
  • Minimal Web API: window, location, navigator.userAgent
  • Document ownership: Rc<RefCell<Document>> for single-threaded renderer
  • ie-wasm: complete instantiate(), memory management, WebAssembly.instantiate() in Boa
  • Tree builder <script> callback, external script fetching
  • Tests: DOM manipulation, event dispatch, timer callbacks, wasm instantiate + call

Parallelism

Steps 1 + 3: fully parallel (no deps between them)
Steps 2, 4, 5, 6: sequential chain
Step 7: after 5 (parallel with 6)
Step 8: after 2 (parallel with 6+7)

What's Deferred (Phase 3+)

  • CSS Grid, transitions/animations, transforms, gradients
  • @font-face (system fonts only in Phase 2)
  • Image rendering (PNG, JPEG, WebP, SVG)
  • <canvas>, <video>, <audio>
  • Scrolling (scroll containers, scroll bars, hit testing)
  • Form elements (<input>, <select>, <textarea>)
  • fetch() API, Shadow DOM, @media query evaluation
  • Accessibility, DevTools protocol

Acceptance Criteria

  • mise run check passes (all crates)
  • html5lib tokenizer conformance suite passes
  • html5lib tree construction suite >95% pass rate
  • cargo run -p ie-shell renders actual web pages (text, colored blocks, flexbox)
  • Browser chrome (address bar, tab list) rendered via GPU pipeline
  • JavaScript DOM manipulation works
  • Headless rendering tests pass in CI (software GPU)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions