Skip to content

v0.2.1

Choose a tag to compare

@brainkim brainkim released this 15 Oct 21:44
· 286 commits to main since this release

TermDOM follows the web platform specifications where they apply. Where it departs from one, these notes say so.

0.2.1 makes TermDOM faster, and makes what it draws after any change match what it draws for the same page from scratch. It also lines up inline-blocks on the baseline, binds the DOM's interfaces the way Web IDL specifies, and lets a program measure the terminal's cell.

Added

  • term.measureCell() (#155) asks the terminal for its cell in pixels and resolves to {width, height}, or null when there is no terminal to ask or it doesn't answer. A cellchange event on the TermDOM announces a new measurement, such as after a font zoom. Cells are seldom square, so anything drawn to a cell's true shape divides by it (#154):

    const cell = await term.measureCell();
    const aspect = cell ? cell.height / cell.width : 2;
  • failFast (#150) ends the session at the first uncaught error, with status 1 and the error printed below the last frame. Over SSH only the failing client is disconnected. It's meant for development:

    new TermDOM({failFast: process.env.NODE_ENV !== "production"});
  • display: inline-table lays out as a table on its line. It laid out as a block before.

  • counters(), and counter properties on ::before and ::after, so h2::before { counter-increment: section } numbers headings. Counters pass from an element to its next sibling, counter-set works, and counters follow the flat tree through shadow trees and slots.

Performance

  • A frame repaints only the rows that changed (#153). Typing in CodeMirror repaints about 3 rows instead of 40.
  • Key-to-frame latency with every core busy is down about a third, and a plain <input>'s by 38–44%.
  • Restyling and building pages: a :has() toggle over 500 items is 85% faster, building and removing 20,000 spans 58%, and startup 29%.
  • Scrolling an inset box writes a fraction of the bytes: 3 KB instead of 68 KB for a box of images (#152).
  • Changing many siblings at once no longer rebuilds their container once per sibling (#149).

Changed

  • Atomic inlines sit on the baseline (#153). The text beside an inline-block lines up with its last line, beside an inline-table, inline-grid or inline-flex with its first row, and beside an image or a box that clips with its bottom edge. vertical-align: top, middle and bottom place a box against the line instead. They used to sit at the top of the line and fill it.
  • Web IDL bindings (#148). DOM methods check their this and arguments, with Chrome's error messages. Members live on the interfaces the specs put them on, and constructing Element, Node and the like throws "Illegal constructor". Internal state is hidden from pages, as in a browser. TermDOM's events and abort signals work with the runtime's own, both ways.
  • Ctrl+Z stops the whole process group (#147), as the terminal does, so it works under launchers such as npm bins. ProcessLike no longer has pid.
  • table-layout: fixed (#147) takes column widths from the first row, and a cell's width is only its column's preferred width, as in browsers. Email wrapped in 600px containers no longer runs off the screen.
  • contain, transform, filter and will-change give fixed boxes a containing block (#147), and paint containment clips.
  • Table parts outside a table share an anonymous table, so cells sit side by side, and text a script puts in a table gets a row (CSS 2.1 §17.2.1).
  • Each key, click and paste is its own task (#152), so a listener's microtasks settle before the next key arrives.

Fixed

  • A page could drift from a fresh render of the same markup after changes. Layout, style and repaint are now checked against results computed from scratch on every frame of every test, and seeded random changes against fresh renders (#153). Over 40 such bugs are fixed, among them stale boxes after display changes, sticky boxes inside inline-blocks, positioned table parts, and form controls not showing their state.
  • A focused, empty textarea in a flex row drew its caret on its top border.
  • Under the default cell, a font zoom left images at the size the old cell gave them (#155).
  • An image at width: 100% in a table ran a cell past its cell (#147).
  • A program crashed on resume when the terminal didn't answer the cursor query (#147).
  • A requestAnimationFrame loop that never stops locked the program (#149).
  • 2D canvas text vanished under any translucent fill (#149).
  • A caret between inline boxes was drawn inside a box's padding (#152).
  • Blank lines written as &nbsp;, as Outlook writes them, were dropped.