Skip to content

TermDOM 0.1.9

Choose a tag to compare

@brainkim brainkim released this 29 Sep 19:48

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

Added

  • Word and paragraph selection. A double click selects the word under the pointer and a triple click the paragraph, as the default action of mousedown. A drag that follows extends by whole words or paragraphs. In a textarea a triple click takes the line, and in an input the whole value.
  • Word editing. Fields and contenteditable move and delete by word with Ctrl or Alt and an arrow, Alt+B and Alt+F, Alt+Backspace, Ctrl or Alt+Delete, and Alt+D. Contenteditable also takes readline's Ctrl+A, E, B, F and D.
  • Alt and the other modifiers. ESC and a key in one read is that key with Alt, as a terminal sends it. CSI u, xterm's modifyOtherKeys, and modified tilde and F1–F4 sequences decode, so Ctrl+Shift+A, Shift+Enter and Ctrl+Delete reach the page.
  • Ctrl+L redraws the screen, as a terminal program does, unless the page cancels the keydown.
  • text-overflow. A clipped line that runs past its end edge ends in an ellipsis. The two-value form and string markers, from the css-overflow-4 draft, mark the left and right edges separately.
  • Pointer events fire before each mouse event, and a canceled pointerdown withholds that press's mouse events. The pointer reaches elements inside an author's shadow root, and mouse, key, input, paste and focus events are composed.
  • Implicit submission. Enter in a text field clicks the form's default button, or submits a form with one field and no submit button. A method="dialog" form closes its dialog with the submitter's value.
  • Fragment navigation. Following a link to #id, or setting location.hash, href, assign() or replace() to a fragment of the document, updates the URL, moves :target, scrolls the target into view and fires hashchange.
  • Named access on the window. An element's id, or the name of an embed, form, img or object, is a property of window: the element, or a live collection when several share the name.
  • document.all, every element in tree order, by index, id, or the name of the elements HTML lists. It departs from the standard in three ways no JavaScript object can avoid: it is not falsy, its typeof is not "undefined", and it cannot be called.
  • CSS nesting, with & and nested rules, and the :heading pseudo-class.
  • The font shorthand sets its longhands and serializes back. A system font keyword (menu, caption) names the UA's own font and is kept whole.
  • white-space is the shorthand CSS Text 4 defines, of white-space-collapse and text-wrap-mode, and text-wrap sets text-wrap-mode and text-wrap-style. Either longhand can be set on its own and lays out accordingly, except that preserve-breaks with nowrap, a pair no white-space keyword stands for, lays out as pre-line, which wraps.
  • Constraint validation pseudo-classes. :valid, :invalid, :in-range and :out-of-range match the validity the engine computes.
  • scrollend, and scrollIntoView takes its block and inline options.
  • navigator.userActivation reports transient activation.

Changed

  • An exception a page lets escape no longer touches the screen. One from a listener, observer, frame or idle callback, or custom element reaction is reported like a browser reports it: the window hears an error event, and an unhandled one goes to stderr when stderr is not the terminal, or is printed below the document when the session ends, however it ends. The app keeps running. An error listener that throws is reported once rather than fired again. A failure in the engine's own rendering hands the terminal back before it surfaces. Exceptions and rejected promises outside the callbacks TermDOM runs, such as an async listener's rejection or a throw in a timer, still end the process as the runtime decides.
  • The computed display is blockified as CSS Display says: the root, absolutely positioned, fixed and floated boxes, and flex and grid items report block, flex or grid.
  • font-weight computes to a number: bold is 700, normal is 400, and bolder and lighter step from the parent's weight.
  • keyCode is the key's, not the character's: 189 for _, as a browser reports it.
  • innerText is the rendered text HTML specifies, not textContent.
  • Selection.toString() is the selected text as it renders: hidden and user-select: none content is left out.
  • Button-type inputs draw their label in brackets, like a <button>, instead of an empty field.
  • screenX and screenY report the pointer's cell on the terminal.
  • Faster and smaller. Styling tries only the rules an element's id and classes could match, and elements alike in their rules, attributes and parent share one set of computed values. A page of simple elements holds about 5.3KB an element, down from 8.4KB, and getComputedStyle keeps under 100 bytes an element, down from 85KB. Typing in a 2,000-line CodeMirror document takes 11ms of CPU a key, down from 17ms.

Fixed

  • A process without a terminal ran on after the process that piped its stdin had exited.
  • The caret showed while a selection held text, so a triple click in CodeMirror seemed to put the cursor on the next line.
  • A field inside a shadow root showed no caret, and keys went to the shadow host instead of the focused field.
  • A focused element that a :focus rule hid kept the focus, and removing the focused element left :focus-within on its ancestors.
  • Removing the pressed or hovered element dropped :active or :hover from its ancestors without restyling them. The state now moves to the parent, as in Firefox and Chrome.
  • A ResizeObserver or IntersectionObserver created after the page settled never got its first observation.
  • An inline flex or grid item holding a block was split into pieces laid out side by side with the container's gap between them. It is now one block container.
  • An inline broken around a block laid out what it held twice, which drew an inline-block one width to the right of its box.
  • Changing an element's display between kinds such as block and inline-block, or to display: contents, could leave its old box standing.
  • A body that is inline, inline-block or display: contents painted nothing.
  • An empty list item had no line for its marker, so the marker took no row.
  • min-width, min-height, max-width and max-height ignored box-sizing: content-box, measuring the border box.
  • text-align had no effect inside an inline-block, and a line too long for its box was not start-aligned, so in a right-to-left box it did not overflow to the left.
  • On a scrolled document, mouse events reported page coordinates as clientX and clientY, so CodeMirror placed a click below the pointer.
  • A child that overflowed its unclipped parent could not be clicked.
  • A press and release on different elements clicked nothing, where UI Events clicks their nearest common ancestor. A double click was counted by element, so it failed when the first click changed what was under the pointer; it is now counted by place.
  • A removed element kept its pending pointer capture, and blur() on a host that delegates focus did not unfocus the element inside it.
  • scrollTo past the end read back the requested position until the next frame, and fired a scroll event for a position that never showed.
  • Two TermDOM windows in one process shared one custom element registry, so the second could not define an element the first had.
  • select.options[1], form.elements[0], document.forms[0] and other collections were undefined until something read their length.
  • A program that ran fullscreen from its first frame left a blank line under the prompt when it exited.
  • The published type declarations referred to Trusted Types typings that TypeScript's DOM library does not have.

These release notes were generated by Claude Code.