unstale

npm / @chenglou/pretext

@chenglou/pretext

What changed in @chenglou/pretext 1, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-27.

39 breaking8 new APIs and options3 performance4 behavior and defaults22 fixes and other

See which of these apply to your code, ranked, in your agent:

npx @unstale/cli init

@unstale/cli 0.2.8 on npm

@chenglou/pretext 176 changes

Breaking changes 39

  • An atomic rich-inline item's own leading or trailing whitespace no longer creates a gap; a whitespace-only atomic item is an empty box sized by extraWidth.

    1.0.0upgrade guide

  • Unrecognized browser layout engines now use Chrome's rules throughout.

    1.0.0upgrade guide

  • In jsdom and happy-dom, which lack a 2D canvas context, preparing text now throws the missing-Canvas error rather than a TypeError about null.

    1.0.0upgrade guide

  • Chrome now applies text-spacing-trim widths to CJK punctuation pairs and line endings, including across rich-inline item boundaries.

    1.0.0upgrade guide

  • The npm package no longer includes pages/demos and pages/assets; they remain in the repository.

    1.0.0upgrade guide

  • Passing a font string that Canvas ignores, such as an empty one, now throws a RangeError.

    1.0.0release notesupgrade guide

  • Safari now measures generic font families using the fonts it draws for the page's language.

    1.0.0upgrade guide

  • glue is removed; no-break spaces and word joiners are text, and zero-width-glue and control are added.

    1.0.0upgrade guide

  • The width argument now precedes the cursor, so callers must swap the second and third arguments.

    1.0.0release notesupgrade guide

  • The width now precedes the cursor, and the first line is returned without a cursor; swap the second and third arguments at existing calls.

    1.0.0upgrade guide

  • When the first word exceeds the line width, a following space or zero-width space now ends the line instead of being moved by other content or letter spacing.

    1.0.0upgrade guide

  • Preparing text now throws a RangeError when letterSpacing is not finite.

    1.0.0upgrade guide

  • Chrome and Firefox no longer add letter spacing after joined-script letters; Safari continues to space each glyph it draws.

    1.0.0upgrade guide

  • Chrome and Firefox now measure text with fi, fl or ffi ligatures as browsers draw it when letter spacing disables those ligatures; Safari remains narrower for this case.

    1.0.0upgrade guide

  • Safari now counts spacing after each glyph it draws in complex text and combining-accent words; measuring glyphs requires additional Canvas calls.

    1.0.0upgrade guide

  • Safari no longer adds letter spacing after U+0085 next-line characters, except next to complex text.

    1.0.0upgrade guide

  • Chrome, Safari and Firefox line-break opportunities now come from ports of each browser's line breaker and data, changing breaks to match browsers in more cases.

    1.0.0upgrade guide

  • Safari now ends lines at U+2028 and U+2029 in normal white space, pre-wrap and rich-inline items.

    1.0.0upgrade guide

  • Negative maxWidth now behaves as zero in plain-text and rich-inline layout; rich-inline widths below 1px also follow the plain-text behavior.

    1.0.0upgrade guide

  • Firefox no longer adds a space for newlines between East Asian characters other than Hangul, or next to East Asian punctuation on ja and zh pages.

    1.0.0upgrade guide

  • Chrome and Firefox no longer add a space for a newline next to a zero-width space in normal white space.

    1.0.0upgrade guide

  • Runs of no-break spaces between other break opportunities now break where they overflow a line, matching browsers.

    1.0.0upgrade guide

  • Runtimes without navigator.userAgent now follow Chrome's rules; outside browsers, measurement uses a global OffscreenCanvas defined before the first prepare().

    1.0.0upgrade guide

  • Handles now expose only segments, kinds and widths; callers must change reads of any other handle field.

    1.0.0release notesupgrade guide

  • Handles made by 0.0.9 must not be kept; prepare the text again.

    1.0.0release notesupgrade guide

  • prepareWithSegments() no longer returns approximate bidi levels per segment; render a paragraph as one DOM element with its direction set to get browser ordering.

    1.0.0upgrade guide

  • A font string that Canvas ignores, such as an empty one, now throws a RangeError.

    1.0.0release notes

  • Rich-inline line and range cursors no longer index an item's text and are only for passing back to layout functions; use source offsets to find fragment text.

    1.0.0upgrade guide

  • Rich-inline items are laid out as one paragraph: break opportunities come from their joined text, and each item is measured in its own font.

    1.0.0upgrade guide

  • Rich inline accepts { width } boxes for images, emoji, formulas, badges and other inline objects; lines can break before and after a box.

    1.0.0upgrade guide

  • segLevels is gone; callers that read it must change.

    1.0.0release notesupgrade guide

  • The locale now controls language-sensitive line breaking and measurement instead of overriding <html lang>; omitting it restores the page language, while an empty string means no page language.

    1.0.0upgrade guide

  • Firefox now collapses spaces on both sides of a soft hyphen into one space.

    1.0.0upgrade guide

  • When a chosen soft-hyphen hyphen does not fit, layout now uses the latest earlier break that fits; Chrome's visible hyphen no longer receives letter spacing.

    1.0.0upgrade guide

  • In pre-wrap text, tab stops now follow browser behavior, including browser-specific letter-spacing calculations and wrapping of tabs that do not fit.

    1.0.0upgrade guide

  • Firefox treats lone carriage returns and form feeds as zero-width, including at rich-inline item boundaries; CRLF remains one space.

    1.0.0upgrade guide

  • Safari treats a lone carriage return as zero-width in normal white space, with line-ending behavior depending on the text; CRLF remains one space.

    1.0.0upgrade guide

  • A line containing only soft hyphens before a newline now counts as a line.

    1.0.0upgrade guide

  • Wrapped lines no longer count trailing spaces in their width, and trailing spaces and tabs are measured and kept on lines as browsers lay them out.

    1.0.0upgrade guide

New APIs and options 8

  • Rich-inline fragments identify which item owns the collapsed space measured by gapBefore, or use -1 when no space precedes the fragment on its line.

    1.0.0upgrade guide

  • Now accepts a prepare() handle, avoiding the need to retain every segment string when only line statistics are needed.

    1.0.0upgrade guide

  • Now accepts a prepare() handle, avoiding the need to retain every segment string when measuring natural width.

    1.0.0upgrade guide

  • An options argument with whiteSpace: 'pre-wrap' enables CSS pre-wrap behavior across styled runs, including preserved whitespace, line-ending newlines and line-start tab stops.

    1.0.0upgrade guide

  • An options argument with wordBreak: 'keep-all' enables CSS keep-all line breaking for rich-inline paragraphs.

    1.0.0upgrade guide

  • Rich inline lays its items out as one paragraph, as a browser lays out a paragraph’s spans.

    1.0.0release notes

  • Read a fragment’s sourceStart and sourceEnd instead of reading rich-inline cursors as places in an item's text.

    1.0.0release notesupgrade guide

  • Now accepts a prepare() handle, avoiding the need to retain every segment string when only line ranges are needed.

    1.0.0upgrade guide

Performance 3

  • At a new width, layout is three to six times as fast as in 0.0.9.

    1.0.0release notes

  • Preparing text it has measured before is 1.1 to 13 times as fast as in 0.0.9.

    1.0.0release notes

  • Preparing and measuring rich-inline paragraphs is reported as faster for both new and previously measured paragraphs in the Markdown chat demo.

    1.0.0upgrade guide

Behavior and default changes 4

  • Pretext now uses each browser's character rules instead of Intl.Segmenter, which remains needed only for text in Southeast Asian scripts written without spaces.

    1.0.0upgrade guide

  • Pretext uses a port of each browser’s own line breaker and data to find line-break opportunities instead of its own rules.

    1.0.0release notes

  • Read a fragment’s sourceStart and sourceEnd instead of reading rich-inline cursors as places in an item's text.

    1.0.0release notesupgrade guide

  • Shared measured-text caches are bounded; after more than 262,144 segments, the next preparation empties them before measuring, while existing handles retain their widths.

    1.0.0upgrade guide

Fixes and other changes 22

  • Firefox now breaks around bidi controls as if they were absent, including their effects on line width, spacing and adjacent accents.

    1.0.0upgrade guide

  • Text using a web font split by unicode-range no longer retains a fallback font's space width after preparation without a character from the space's font subset.

    1.0.0upgrade guide

  • Chrome and Firefox on macOS now measure text-font emoji and system-fallback emoji sequences more closely to their drawn widths at small sizes.

    1.0.0upgrade guide

  • Chrome and Firefox on macOS no longer measure U+FE0F after a non-emoji character narrower than the browser draws it at small sizes.

    1.0.0upgrade guide

  • Emoji widths no longer become permanently zero when first prepared while body is display:none, and page CSS no longer skews their measured width.

    1.0.0upgrade guide

  • Chrome now uses fonts for a newly changed html lang value even when the font string is unchanged.

    1.0.0upgrade guide

  • Chrome and Firefox now let ideographic spaces hang past the end of a line instead of wrapping them.

    1.0.0upgrade guide

  • Chrome on macOS now accounts for kana kerning when measuring Japanese lines; name a Japanese font after a font list that Chrome Canvas does not shape as a whole.

    1.0.0upgrade guide

  • Firefox now applies letter spacing in whole increments of 1/60px, matching its layout and preventing small line-wrap discrepancies.

    1.0.0upgrade guide

  • Safari now retains a word's kerning with a following space, both with and without letter spacing.

    1.0.0upgrade guide

  • Chrome line widths now account for kerning between spaces and neighboring words, preventing lines and widest-line-sized bubbles from exceeding Chrome's layout.

    1.0.0upgrade guide

  • Reported line widths are clamped at zero instead of becoming negative, for example under strongly negative letter spacing.

    1.0.0upgrade guide

  • Words wider than a line now account for kerning when choosing cuts, more closely matching Chrome and Firefox; measurements cost more when such a word is first prepared.

    1.0.0upgrade guide

  • Ranges ending past their prepared text now materialize only text up to the range end instead of appending undefined or potentially iterating until memory runs out.

    1.0.0upgrade guide

  • In Firefox, zero-width break: 'never' items and zero-width boxes that fall past a full line now land on the line Firefox uses.

    1.0.0upgrade guide

  • Rich-inline line-start fragments now begin after spaces and soft hyphens skipped at line starts, including under negative letter spacing.

    1.0.0upgrade guide

  • Rich-inline layout now keeps text or a break: 'never' item on a line when its overflow is within 0.005px, or 1/64px in Safari.

    1.0.0upgrade guide

  • A line ending at a soft hyphen is measured with U+2010 HYPHEN when the font has one, while the line's text still ends with a hyphen-minus.

    1.0.0upgrade guide

  • Browsers and in-app web views on iPhone, iPad and Mac now use Safari's WebKit wrapping rules; Safari worker preparation uses the same rules as page preparation.

    1.0.0upgrade guide

  • Chrome and Firefox no longer lose text when a URL contains a second www. or scheme before its query.

    1.0.0upgrade guide

  • Paragraphs made only of zero-width spaces now occupy one line instead of disappearing.

    1.0.0upgrade guide

  • A zero-width space at paragraph or hard-line start no longer disappears when following text wraps.

    1.0.0upgrade guide