Skip to content

0.1.10

Choose a tag to compare

@brainkim brainkim released this 02 Oct 02:58
· 866 commits to main since this release

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

Most of these fixes came from rendering real HTML email in the terminal.

Added

  • cellSize, how many CSS pixels one terminal cell is. Leave it alone for apps written for the terminal. Set it to "auto" to show pages written for a browser, like a 600px-wide email, at about the size they'd be in one.

    new TermDOM({cellSize: "auto"});

    "unit", the default, keeps a cell at 1×1 px as before. "auto" takes the size the terminal reports, or 8×16 if it can't say; the first frame waits for the answer, a second at most, and a font zoom asks again. {width, height} sets a fixed size. A box's edges round to the nearest cell, so columns that add up to their container still fit it. See the API guide.

  • The lh and rlh units, one row as the terminal draws it.

  • term.renderANSI() and term.print() with no argument render the document as it stands.

  • prefers-color-scheme follows the terminal. TermDOM asks whether the terminal's background is dark (OSC 11, falling back to COLORFGBG), and the color media features report the colors the terminal actually draws.

  • Media queries evaluate as Media Queries 4 says, including its "unknown" results, and a matchMedia list serializes as CSSOM does.

  • The absolute units in, cm, mm, q, pt and pc.

  • HTML's legacy attributes (align, bgcolor, width, border and the rest) map to style as HTML's Rendering section says, and <center> and align center their content as browsers do.

Changed

  • ch is one cell along the axis it's used on: a column in width, a row in height. CSS measures ch across on both axes; a cell grid doesn't.
  • Unstyled text starts as CanvasText, the terminal's own color, as CSS specifies, rather than #000000.
  • getComputedStyle reads system colors back as rgb(), as browsers do. Colors the terminal fills in, like CanvasText, read as black or white to match its light or dark theme.
  • Blockquotes get a left border and 1ch of padding by default.
  • Table cells center vertically by default, as HTML's rows do, and a row's baseline cells line up their first lines.
  • Inline boxes take their left and right margin, border and padding.
  • An auto-width inline-block shrinks to fit its line.
  • width and height size the box that box-sizing names.
  • A broken terminal stream closes the session instead of crashing the process.
  • Node 20.19 or later is required. The CommonJS build loads css-tree's ES module, which older Node 20 can't require().

Fixed

  • Security: inline event handlers (onclick, ontoggle, ...) ran in documents without a window: DOMParser results, createHTMLDocument(), <template> contents and iframe documents. An engine-fired event such as <details open>'s toggle ran the handler while markup was being parsed, before a sanitizer could remove it. If you sanitize untrusted HTML, upgrade. Thanks to @titanism (#128).
  • color: #000000 drew in the terminal's default color, light gray on a dark theme.
  • direction: rtl didn't reverse inline-blocks.
  • A percentage max-width on an inline-block resolved against the box itself, and max-width and min-width didn't clamp an inline-block's width.
  • A block with margin: auto shrank to its content instead of filling its container.
  • A table cell's percentage width was of the table's container, not the table.
  • padding: 0 on a table cell still left a column on each side.
  • Whitespace between boxes took a cell at font-size: 0, so rows of inline-block columns wrapped.
  • A scroller didn't clip position: relative content, which painted over what sat above it.
  • Inline-block content stopped painting once anything scrolled, so MJML emails went blank.
  • scrollWidth missed text that doesn't wrap.
  • getBoundingClientRect ignored text-align for inline-blocks, and the scroll of a scrolling flex item holding text.
  • scrollIntoView({block: "nearest"}) scrolled a box taller than its scroller to its end.
  • After Enter, the caret went inside the new line's <br>, so fast typing was lost.
  • Clicking an empty line put the caret nowhere, and arrow keys could move the caret out of view or off its column.
  • Mouse selection didn't work inside shadow roots, or from a drag that began in padding or margins.
  • Nested tables took time exponential in their depth. 60 levels of email tables hung the process.
  • <style> blocks in a shadow root restyled the root once per rule, and parsing deeply nested markup took quadratic time.
  • Compiled binaries (bun build --compile, deno compile) failed at startup on css-tree's JSON.
  • focus(), and so Tab, didn't always scroll the element into view.
  • A piped document could print more than the document, and measuring missed content past the root's box.
  • A scroll container didn't scroll over its children's overflow, and a scrolling flex or grid item couldn't shrink below its content.
  • IntersectionObserver parsed rootMargin differently from the spec.
  • A cached layout could outlive a sizing pass and paint stale positions.

🤖 Generated with Claude Code