Skip to content

Update frontend dependencies (dev) (major) - #4017

Open
renovate[bot] wants to merge 1 commit into
devfrom
renovate/dev-major-frontend-dependencies
Open

renovate[bot] wants to merge 1 commit into
devfrom
renovate/dev-major-frontend-dependencies

Conversation

@renovate

@renovate renovate Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence Type Update Pending
@chenglou/pretext ^0.0.9 → ^1.0.0 age confidence dependencies major
@eslint/compat (source) ^1.4.1 → ^2.0.0 age confidence devDependencies major
@eslint/js (source) ^9.39.5 → ^10.0.0 age confidence devDependencies major
@scure/base (source) ^1.2.6 → ^2.0.0 age confidence dependencies major
@tanstack/react-table (source) ^8.21.3 → ^9.0.0 age confidence dependencies major
@testing-library/jest-dom ^6.10.0 → ^7.0.0 age confidence devDependencies major
@types/node (source) ^22.20.5 → ^26.0.0 age confidence devDependencies major
@​types/totp-generator ^0.0.8 → ^2.0.0 age confidence devDependencies major
@vitest/ui (source) 4.1.9 → 5.0.5 age confidence devDependencies major 5.1.0
dotenv ^17.4.2 → ^18.0.0 age confidence dependencies major
eslint (source) ^9.39.5 → ^10.0.0 age confidence devDependencies major
eslint-plugin-simple-import-sort ^12.1.1 → ^14.0.0 age confidence devDependencies major
jsdom ^29.1.1 → ^30.0.0 age confidence devDependencies major 31.0.0
node (source) 19.9.0 → 26.13.0 age confidence volta major
radashi (source) ^12.9.6 → ^13.0.0 age confidence dependencies major 13.0.4 (+2)
react-intersection-observer ^10.1.0 → ^11.0.0 age confidence dependencies major
totp-generator ^1.1.0 → ^2.0.0 age confidence dependencies major
typescript (source) ~6.0.3 → ~7.0.0 age confidence devDependencies major
vitest (source) 4.1.11 → 5.0.5 age confidence devDependencies major 5.1.0

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Release Notes

chenglou/pretext (@​chenglou/pretext)

v1.0.0

Compare Source

Upgrading from 0.0.9
  • layoutNextLine() and layoutNextLineRange() take the width before the cursor, (prepared, maxWidth, start?), as layoutNextRichInlineLineRange() does, and give the first line without a cursor: swap the second and third arguments at every call. TypeScript reports each call left in the old order; in JavaScript, search for the two names, since a call left in the old order never returns null (#​496).
  • Rich-inline cursors are only for passing back: a line's end and a fragment range's start and end no longer index the item's own text, and a materialized fragment's type no longer has start and end, so code that read them there no longer compiles. Read its sourceStart and sourceEnd instead, and keep the range of a line you pass back (#​460, #​483).
  • The type of a prepareWithSegments() handle shows only segments, kinds and widths, all read-only: copy one before passing it on as an array or calling array methods on widths (prepared.segments.slice(), Array.from(prepared.widths)), call measureNaturalWidth() for a text's width, and read a line's width for a line's (#​450).
  • segLevels is gone: paint each paragraph of mixed-direction text as one DOM element with its direction set (#​258).
  • In kinds, 'glue' is gone, a run of no-break spaces being 'text', and 'zero-width-glue' and 'control' are new (#​240, #​340).
  • setLocale(locale) now sets the language text is laid out under, in place of <html lang>: pass the page's language, not the user's, or drop the call. setLocale() with no argument goes back to <html lang>, and setLocale('') no longer does (#​340, #​356).
  • Don't deep-freeze a handle, and prepare the text again in place of a handle that 0.0.9 made (#​340, #​460).
  • A letterSpacing that isn't finite now throws a RangeError when preparing (#​356).
  • A font string that Canvas ignores, such as '', '16px' or 'Arial 16px', now throws a RangeError when preparing: check what getComputedStyle(el).font gave before passing it on (#​502).
  • Put the space next to a break: 'never' item in the text beside it: the item's own leading and trailing white space no longer makes a gap, and an item of only white space is an empty box as wide as its extraWidth. An item of only a zero-width space or soft hyphens, such as an editor's placeholder, gets no fragment on a line whose start consumes it, as after a space that ends the line before (#​369, #​460).
  • In TypeScript, an entry of prepareRichInline()'s list may be a box, so check its text before reading its font; a run type of your own can't carry a width; a fragment range built by hand needs gapItemIndex, and a materialized fragment sourceStart and sourceEnd too, and no start or end; and paragraphs.map(prepareRichInline) needs an arrow function, items => prepareRichInline(items) (#​310, #​379, #​387, #​460, #​483).
  • The demos are in the repository, no longer in the package (#​342).
Added
  • Rich inline takes boxes, { width } (RichInlineBox), for an image, a custom emoji, a formula or a badge inside a line, in place of a character with break: 'never' and an extraWidth that made up the rest of the object's width. A line can break before and after a box, as at an <img>, whatever text touches it, and its fragment has the box's width and no text. Heights stay yours: give each box vertical-align: top, and each line is as tall as the paragraph's line height or its tallest box, whichever is taller. prepareRichInline() now takes Array<RichInlineItem | RichInlineBox>, so code typed from its parameter checks an item's text before reading its text or font, and RichInlineItem has width?: never, so an app whose own run type carries a width beside its text no longer type-checks at prepareRichInline(): pass such runs without that field, or name it otherwise; at run time such an item still lays out as text (#​387).
  • prepareRichInline() takes an options argument, { whiteSpace: 'pre-wrap' }, for CSS white-space: pre-wrap on the paragraph, as prepare() does: every item but an atomic one keeps its spaces, tabs and newlines, spaces at a line's end hang past it across a change of style, tab stops count from the line's start, and a newline ends its line, so an editor's paragraph split into styled runs takes the lines the browser gives it. White space after an atomic item wider than the line stays on that item's line, whatever items it spans; in Firefox, such white space that runs into a tab moves to the next line with the tab. A tab counts its stops in its own item's font, as Safari does; Chrome and Firefox count them in the paragraph's font, so a tab inside a span in another font, such as a code span, can land a whole stop from theirs. paragraphs.map(prepareRichInline) no longer type-checks, since map() hands its index where the options go: write items => prepareRichInline(items) (#​381, #​386, #​395, #​419, #​460).
  • prepareRichInline()'s options argument also takes { wordBreak: 'keep-all' }, for CSS word-break: keep-all on the paragraph, as prepare() does, so Korean, Chinese and Japanese messages with mentions, bold runs or code spans break where the browser breaks them under keep-all (#​379).
  • Rich-inline fragments now have gapItemIndex, the index of the item whose collapsed space gapBefore measures, or -1 when no space precedes the fragment on its line. A painter can draw that space inside the element of the item whose font measured it, and can tell a space that takes no room apart from no space (#​310).
  • Materialized rich-inline fragments now have sourceStart and sourceEnd, where the fragment's text sits in its item's text, as UTF-16 offsets: of the items Ship and it now, the fragment it now is 1 to 7. Read them where code written for 0.0.9 read the fragment's start and end as cursors into the item's own text, which they no longer are (under Changed). TypeScript that builds a fragment by hand, as a test does, now has to give it these two and gapItemIndex, and to leave out start and end, which a materialized fragment's type no longer has; a fragment range built by hand needs gapItemIndex (#​460, #​483).
  • walkLineRanges(), measureLineStats(), measureNaturalWidth() and layoutNextLineRange() now also take a prepare() handle, so an app that only needs line counts, widths or cursors, such as a chat bubble shrunk to its widest line, no longer has to keep every segment's string in memory with prepareWithSegments(). layoutWithLines(), layoutNextLine() and materializeLineRange(), which return text, still need prepareWithSegments() (#​449).
Changed
  • Bundles that import Pretext are larger than with 0.0.9: the main entry is about 40 KB gzipped (95 KB minified), up from 16 KB (48 KB), and @chenglou/pretext/rich-inline about 44 KB (107 KB), up from 16 KB (49 KB). About 23 KB gzipped of each is each browser's line-break and grapheme data with the code that reads it, which replace Pretext's own break rules and the Unicode bidi-class table that 0.0.9 bundled for segLevels. The npm package is 56 files and about 1,030 KB unpacked, where 0.0.9 was 69 files and 887 KB, 534 KB of it the demos, which have left the package (#​258, #​311, #​340, #​342, #​344, #​392, #​394, #​403, #​460, #​515).
  • Speed against 0.0.9, timed in Chrome 154, Firefox 157 and Safari 27 on an M5 Max MacBook Pro, on chat-like messages (#​338, #​340, #​344, #​351, #​365, #​375, #​383, #​400, #​407, #​435, #​445, #​453, #​460, #​497, #​512, #​513, #​515):
    • Faster: layout() at a new width is three to six times as fast. measureLineStats() and walkLineRanges() are 1.8 to 4.9 times as fast, layoutWithLines() 1.3 to 1.7 times and layoutNextLineRange() 1.1 to 2.2 times. prepare() of text it has measured before, as when a list prepares its messages again, is 1.1 to 13 times as fast: two to three and a half times for English text, 6 to 13 times for Chinese and Japanese, least for Thai. Text it hasn't measured before is about 1.5 to 2.1 times as fast for English, Chinese and Japanese, 1.1 to 1.6 times for messages that mix scripts, and from level to 1.7 times for Arabic and Thai. Rich inline, timed on the Markdown chat demo's paragraphs (English, most of them one item), prepares and measures new ones about 1.4 to 1.9 times as fast and ones it has measured before 2.3 to 4.8 times as fast. measureRichInlineStats() is two to three times as fast there, and walkRichInlineLineRanges() and layoutNextRichInlineLineRange() 1.1 to 1.9 times, least on paragraphs of several styled items. Worst-case text, such as letter-spaced CJK, soft hyphens among combining marks, long unbroken runs and pre-wrap text, is faster too, in prepare() and in layout().
    • Slower: loading the library, timed as a bundle of both entry points, takes about 0.4 ms more on each page in Chrome, 0.7 ms in Safari and 1.1 ms in Firefox, and the first text a page prepares, its first few hundred to a thousand characters, takes about 0.5 to 0.8 ms more in Chrome, 0.6 to 1.1 ms in Safari and up to 0.3 ms in Firefox; in Chrome and Safari the text after that is already level or faster. In Safari, letter-spaced Hindi and Arabic text prepared again after clearCache() takes 9% to 15% longer, since Pretext now asks Canvas how many glyphs Safari spaces (#​513, under Fixed). The first prepare() of interface labels is slower in some languages, most of them with long words, though labels of 35 languages mixed are level or faster in the three browsers. Most of that cost is the widths a word 80px or wider now gets for each of its letters when it is first prepared, for a line narrower than the word, which cuts it between letters.
  • In pre-wrap text, tab stops now follow each browser. Chrome and Firefox count letter spacing in every stop, so a run of tabs under negative letterSpacing no longer collapses to one stop's width. A tab closer to its stop than the browser's minimum, half a space in Chrome and Safari and half a 0 in Firefox, takes the stop after it. In Firefox, which doesn't hang tabs, a word whose tab doesn't fit moves to the next line with the tab, so tab-separated text such as a pasted table or indented code wraps where Firefox wraps it (#​240, #​395).
  • A rich-inline atomic item's (break: 'never') own leading or trailing white space no longer gives a gap before or after it, as browsers trim that white space inside the item's box: where only that white space stood, gapBefore is now 0, and gapItemIndex -1, where 0.0.9 measured a space in the atomic item's font. An atomic item of only white space is an empty box as wide as its extraWidth, as browsers lay out an inline-block that holds only white space, where 0.0.9 made it a collapsed space with no extraWidth (#​369, #​460).
  • Pretext now finds grapheme clusters with the character rules each browser ships instead of Intl.Segmenter, which it needs only for text in Thai, Lao, Khmer, Myanmar and the other Southeast Asian scripts written without spaces (#​344).
  • Chrome, Safari and Firefox now find where lines can break with ports of each browser's own line breaker and its data, in place of Pretext's own rules, so lines break where the browser breaks them in many more cases, such as around CJK punctuation and quotes, dashes, URLs and Thai (#​340). Among the breaks that moved (#​228, #​232, #​233, #​234, #​240, #​243, #​245, #​249, #​250, #​270, #​276, #​288, #​289, #​290, #​291, #​309):
    • Lines can break after ؟, ؛ or ۔ before a following word, after a ? that follows a space or a zero-width space, and after ! or ? before a symbol such as ©, ¿ or €. In Chrome and Safari they can also break after ? before $, %, +, | or -, while ! still stays with those and with a following ASCII letter or digit; in Firefox they can break after ! before a letter or digit, and ! and ? stay with a following - or |.
    • In Chrome and Safari, a hyphen or dash at the start of a word, such as U+2010 HYPHEN, U+2012 FIGURE DASH or U+2013 EN DASH, stays with the letter after it; - does so only before a letter outside ASCII in Chrome, such as é, and outside Latin-1 in Safari. In Firefox, a hyphen stays with a number after it, as in 2025-08-01 or log-2026, and a line can break after / before a letter, as in and/or or example.com/docs, though not before a number, as in 1/2.
    • A figure space (U+2007) keeps the text on both sides of it on one line, like a no-break space, and a zero-width joiner keeps the character after it. A next-line character (U+0085) stays on the same line as the text before it, and lines can still break after it.
    • Lines no longer start with closing punctuation or other marks that can't start a line, such as 。, ,, 」, 、, ] or ゛: such a mark stays with the text before it, CJK or not, as in xxxx, or 😀。, and after CJK text so do ', /, |, ‼ and %. A word that doesn't fit a line with its mark breaks before the mark.
    • After CJK text, ., ,, :, ;, ), ], % or " keeps a following word or number on its line, and !, }, / or | keeps what each browser keeps: Chrome ASCII letters and digits; Safari digits, and letters only after a } that follows an ideograph or Hangul syllable; Firefox only digits after /. A time or number before closing punctuation such as a full-width comma, as in 00:00:00,, stays whole.
    • In Chrome, lines can break between a fullwidth closing bracket such as 」 or ) and a following ideograph, kana or Hangul syllable.
    • Small kana and ー after CJK text can start a line in Chrome, in Safari only on pages whose <html lang> is Japanese or Korean, and not in Firefox; where they can't, they also stay with a letter or digit before them, as in 約3ヶ月.
    • With word-break: keep-all, lines in Chrome and Firefox no longer break after ー in words such as ラーメン, nor in Chrome after an iteration mark such as 々. In Chrome and Firefox they can break before an opening bracket after CJK text, as in 서울(한국)에서, before 「 or ( after Latin letters or digits, and next to Thai text; in Chrome also next to emoji and symbols such as ★, and before an opening quotation mark or after a closing one between CJK characters, as in 他说“你好”然后; in Firefox also after a flag emoji.
    • Text that stays together on a line, such as 漢。 or 「漢, breaks between characters when it doesn't fit a line, instead of overflowing, and a run of opening brackets stays with the word after it, as in 「「tail.
  • Rich inline now lays its items out as one paragraph, as a browser lays out a paragraph's spans: it finds where lines can break in the items' joined text once and measures each item in its own font, so its lines break where the same text in one element does. Each item continues the line before it, and a line ends between items, or inside one, only where the joined text has a break opportunity, in every browser, in engines Pretext doesn't recognize and in runtimes such as Node, Bun or jsdom. 0.0.9 prepared every item apart and laid each out as if it started a line, so a line could end at any item boundary, or between the letters of an item's first word to fill the line (#​241, #​287, #​301, #​327, #​359, #​369, #​372, #​373, #​460, #​483):
    • Punctuation such as , or ) at the start of an item stays with the word before it, and a word split across items wraps as one word, moving to the next line whole where it doesn't fit. Items without a space between them still break where the joined text allows it, such as between CJK characters, at Thai word boundaries or after -. In Chrome and Firefox, where items split a word, as when part of a Thai or Myanmar word is styled, lines end at that word's own breaks. In Safari, breaks inside each item still come from that item's own text, as Safari wraps each span, so a Thai, Lao, Khmer or Myanmar word split across items wraps like Safari's spans.
    • A soft hyphen that starts an item after other text, or ends an item, is a break there, and a line that ends at it ends with a hyphen, which its width counts and its fragment's text shows; 0.0.9 painted and counted none there. In Firefox that holds before a combining mark too; after an ideograph or emoji such a break needs no room for a hyphen, as Firefox draws none there; two soft hyphens that start an item break as in one element; and so does one right after a space, with no hyphen.
    • An item holding only a soft hyphen is such a break too, and keeps the collapsed space before it, which its fragment names in gapItemIndex; an item that starts with a soft hyphen and a space keeps that space after other text on the line. White space between the soft hyphens of such an item takes room after other text in Chrome and Safari, as in one element, and a line too narrow for anything ends at its first soft hyphen. An item of only soft hyphens or a zero-width space gets no fragment on a line whose start consumes it, where 0.0.9 gave it one that took no room.
    • In Firefox, white space collapses across soft hyphens and bidi controls, invisible direction characters such as U+202A, from one item into the next, as Firefox collapses one run of them whichever element holds it, so an item holding only white space and bidi controls such as LRM between words takes the room of one space, not two, and a soft hyphen or bidi control that starts an item ends that run. In Chrome, a newline next to a zero-width space in the item before or after it goes, as in one element, instead of leaving a space.
    • Cursors changed meaning, which breaks code that read them as places in an item's own text. A line's end and a fragment's start and end now count segments of the item's part of the paragraph, and are only for passing back to layoutNextRichInlineLineRange() and materializeRichInlineLineRange(). On 0.0.9 they indexed the item's own prepared text, prepareWithSegments(item.text), and they no longer do: they differ, among others, for an item that starts with white space after another item's text, whose first segment is now that space; for an atomic item, which is one segment; for an item that starts inside a word whose breaks depend on the whole word, as a Thai word's do in Chrome and Firefox; and for an item with extraWidth that starts with a zero-width space, whose start is now a segment of its own before that space. A paragraph of one text item that isn't atomic and has no extraWidth keeps that text's own cursors. To find a fragment's text in its item, read the materialized fragment's sourceStart and sourceEnd (under Added): its type no longer has start and end, so TypeScript that reads them there no longer type-checks. Nor does a materialized line or fragment where a range is asked, as when a line is passed back to materializeRichInlineLineRange(): keep the range of a line you pass back.
    • Four things got worse. A zero-width space in an item of its own, such as the placeholder an editor keeps in an empty styled run, no longer gets the line of its own that the browser gives it: after a space that ends its line, where the paragraph comes out a line shorter than the browser's for the few pixels of width where that line's text fits and the space doesn't; and after content wider than its line, such as text laid out at a width narrower than a letter or, in Chrome and Safari, an atomic item that doesn't fit. In Chrome and Safari, an item with extraWidth that holds only a zero-width space, such as an empty code span kept open with one, stays on a line where only half its extraWidth, the end padding, doesn't fit, so that line's width is more than maxWidth; 0.0.9 moved it to the next line, which is where those browsers put it after a space. In Firefox, a line that ends at a space before a soft hyphen in another item reports that space in its width, one space wider than Firefox paints. Also in Firefox, where an item ends with a space and the next starts with a bidi control, such as U+200E, and another space, a one-word line that ends at the first space reports that space in its width as well, and a longer line that fits only without that space now gives up its last word to the next line, which Firefox does in some such paragraphs and not in others, so the paragraph can come out a line taller than Firefox's.
  • The values in a prepareWithSegments() handle's kinds changed. 'glue' is gone: a segment of no-break spaces or a word joiner is now 'text', so code that compares a kind with 'glue' no longer type-checks. Two are new: 'zero-width-glue', a zero-width space or soft hyphen the browser doesn't break after, as before a combining mark, and 'control', in Safari a next-line character (U+0085) (#​240, #​340).
  • The type of a prepareWithSegments() handle now shows three read-only fields and nothing else: segments, kinds and widths, each segment's width in px. The eleven others that 0.0.9's type showed are the library's own working data for laying out lines, which changes with engine fixes: six are gone (under Removed), and reading any of the rest no longer type-checks. For a text's width, call measureNaturalWidth(); for a line's, read the line's width. Each letter's width (breakableFitAdvances) and the hyphen's (discretionaryHyphenWidth) have no public equivalent. All three are read-only: to pass one on as a string[] or number[], or to write to it, copy it first, with prepared.segments.slice() or Array.from(prepared.widths). widths is typed ArrayLike<number>, with an index and a length, so for...of, spread and reduce() on it need that copy too (#​450).
  • A handle works only with the version of Pretext that made it: one made by 0.0.9, as kept in IndexedDB or sent by a worker on an older bundle, throws a TypeError in this version's line functions, so prepare the text again. A handle also holds a typed array now, so a deep freeze of one throws; one frozen with Object.freeze() alone, or whose objects and arrays a store froze, still lays out and materializes as it did (#​340, #​460, #​494, #​509).
  • Safari's line breaking follows Safari 27. Safari 26, on macOS 26 and iOS 26, breaks differently around curly quotes and guillemets, after punctuation with word-break: keep-all, and at U+2028 and U+2029 (#​340).
  • In Chrome, text on a page without a lang now breaks and measures under Chrome's UI language, as Chrome lays it out: under a Chinese UI, curly double quotes follow the line-break rules of CJK brackets, so a line can break before “ and after ”, as in 他说“OK”然后, and never right after “ or right before ” (#​340).
  • setLocale(locale) now sets the language that later prepare(), prepareWithSegments() and prepareRichInline() calls break lines and measure under, in place of the page's <html lang>, which a worker doesn't have; setLocale() without a locale goes back to <html lang>, and setLocale('') is a page without a language, where 0.0.9 took an empty string as no argument. It no longer passes the locale to Intl.Segmenter, whose word boundaries Pretext now reads only inside Thai, Lao, Khmer and Myanmar text, where no locale changes them (#​340, #​356).
  • prepare(), prepareWithSegments() and prepareRichInline() now throw a RangeError for a letterSpacing that isn't finite, such as NaN or Infinity, which gave lines of width NaN, or a line per grapheme (#​356).
  • prepare(), prepareWithSegments() and prepareRichInline() now throw a RangeError for a font string that Canvas ignores, such as '', '16px', 'Arial 16px' (the family first) or 'var(--font)'. A Canvas context given such a string keeps the font it had, so 0.0.9 measured the text in whatever font was prepared last, with no error. An empty string is what getComputedStyle(el).font gives for an element that sets a longhand the shorthand can't hold, such as font-variant-numeric, or that isn't mounted yet. Each browser throws for what its own Canvas ignores: Firefox also for a size that isn't an absolute length, such as 1.5em or 100%, and Firefox and Safari for caption and the other system fonts (#​502).
  • The caches of measured text that prepare(), prepareWithSegments() and prepareRichInline() share no longer grow for as long as the page lives, which they did where text never repeats, as ids, numbers and URLs don't. Once they hold more than 262,144 segments between all fonts, the next preparation empties them before it measures anything, as clearCache() does: prepared handles keep their widths, and text prepared afterwards is measured again. For scale, 880,000 UTF-16 units of mixed-language text in one font fill 27% to 43% of that, by browser (#​508).
Removed
  • prepareWithSegments() no longer returns segLevels. Those approximate bidi levels per segment couldn't produce visual order, and computing them slowed every prepareWithSegments() and rich-inline preparation, most for Arabic and Hebrew text. To draw mixed bidi text, render each paragraph as one DOM element with its direction set, and the browser orders every line. Lines drawn separately, such as with Canvas fillText(), are each ordered as their own paragraph, so numbers or punctuation next to a line break can come out in a different order (#​258).
  • A prepareWithSegments() handle no longer has lineEndFitAdvances, lineEndPaintAdvances, breakablePreferredBreaks, spacingGraphemeCounts or chunks, fields README never documented but 0.0.9's published type showed; none has a public equivalent (#​255, #​340).
  • The npm package no longer includes the demos (pages/demos and pages/assets). They live in the repository (#​342).
Fixed
  • A word too long for its line, such as a URL, a message placeholder or a long compound, is now cut where Chrome cuts it when its letters kern, and closer to where Firefox cuts it, in a word 80px or wider. Both browsers fit the letters as the word shapes them, where 0.0.9 added up each letter's own width and so moved a letter to the next line too early, or, where the rest of the word then looked too wide, gave the paragraph a line too many. In Firefox, Pretext still doesn't count the kerning between the last letter of a line and the first of the next where the browser counts it, so where those two letters kern, as in a long run of AV, the cut can still fall a letter from Firefox's and the word take a line more or fewer. Firefox also keeps the letters of a ligature, such as fi in fonts that join it or Armenian ու, on one line, and moves them to the next together where they don't fit; Pretext can still cut between them in a word of more than 96 letters. The widths for this are measured when such a word is first prepared, the cost new labels in languages with long words pay (under Changed) (#​340, #​435).
  • In Firefox, a rich-inline break: 'never' item that takes no room, or a box of width 0, that falls past the end of a full line, as after a space that doesn't fit, now lands on the line Firefox puts it on. It stays at the end of the full line where it is the paragraph's last item, where a box or chip with a width follows it, or text without extraWidth that starts with a space, and in pre-wrap after spaces that hang. It starts the next line where text or an item with extraWidth follows it directly, or where the white space before it follows text already wider than the line. It used to start the next line in every case, which could give the paragraph a line more than Firefox lays out and put the item's fragment, and the height an app gives each line from its boxes, on the wrong line (#​387, #​405).
  • In Chrome, lines no longer come out wider than Chrome lays them out in fonts that kern letters against the space, such as Arial, Helvetica, Times New Roman, Trebuchet MS, Roboto, Avenir Next and Gill Sans. Chrome tightens a space before a capital such as A, T or Y, and in some fonts the space after many words, which Chrome's Canvas doesn't report for words measured apart, so a line with several such words was up to a few pixels too wide: a paragraph of card-length text took a line more than Chrome gave it at about one width in 600 in Arial, and one in 75 in Gill Sans, and a bubble sized to its widest line was that much too wide. Pretext now reads that kerning from Canvas: the first text with a space in a font costs two more measureText calls, which tell whether the font kerns the space, and only a font that does costs more, up to three calls for each distinct first or last character of its words other than ideographs, kana and Hangul syllables, so the first paragraphs in such a font make the most extra calls and later ones next to none. Where a line ends at a word that kerns with the space after it, the word is measured without that kerning, as Chrome lays it out in centered, right-aligned, justified or underlined text and in text directly inside an element with a background; in plain start-aligned text Chrome keeps the kerning there, so such a line can still wrap one word sooner than Chrome, as before, and never later. A font that kerns only characters outside ASCII against the space, as Tamil MN and Malayalam MN do, and text that holds right-to-left letters or a bidi control other than LRM, measure as before. In rich inline, a collapsed space at an item's start or end is measured with that item's text beside it, so gapBefore and the line's width hold this kerning too: A and a space in 16px Arial are 0.88px narrower (#​408, #​423, #​426, #​460).
  • In Chrome on macOS, Japanese lines no longer come out wider than Chrome lays them out in fonts that kern kana, such as the Hiragino fonts and YuGothic, which macOS also falls back to for Japanese text. Chrome kerns two kana in a row, so it fit one more character on a line than Pretext did in about one paragraph in five, and about one in fifty came out a line shorter than layout() said. Under a font list of one family that Chrome's Canvas doesn't shape as a whole, such as "Helvetica Neue" alone, kana that the system's fallback font draws still measure apart: name a Japanese font after it (#​497).
  • In Firefox, a lone carriage return or a form feed in the default whiteSpace: 'normal' now takes no room, as Firefox draws it, inside a rich-inline item and at its start or end too: ab\rcd is as wide as abcd, and a line can still end after ab. Before, it took the room of a space. \r\n is still one space. White space that starts the next rich-inline item after one is measured in that item's own font and letter spacing, as Firefox draws it, where the item that held the carriage return or form feed measured it (#​399, #​460).
  • In Safari, a lone carriage return in the default whiteSpace: 'normal' now takes no room, as Safari draws it, inside a rich-inline item and at its start or end too: ab\rcd is as wide as abcd, and no line ends at the carriage return in text that is all Latin-1; where the text holds characters outside it, such as Cyrillic, Arabic or Chinese letters, a line can end after the carriage return where Safari ends one, as in бв\rcd and not in бв\r12. On 0.0.9 it took the room of a space and a line could end at it, so a line holding one measured a space too wide and a paragraph could come out a line taller than Safari's. \r\n is still one space, and white space that starts the next rich-inline item after a carriage return is measured in that item's own font and letter spacing. One kind of font goes the other way: where the first installed family of a font list is monospace or one of macOS's own fixed-pitch fonts, Menlo, Monaco, Courier, Andale Mono or PT Mono, Safari gives the carriage return a character's width. For one carriage return between two letters the space 0.0.9 gave it was as wide; now a line holding one measures a character too narrow in those fonts, and a paragraph can come out a line shorter than Safari's. Courier New, ui-monospace and web fonts aren't among them (#​455, #​460).
  • In Firefox, spaces on both sides of a soft hyphen, as in ab, space, soft hyphen, space, cd, now take the room of one space, as F

[!IMPORTANT]
✂ PR body was truncated to here.


Configuration

📅 Schedule: (in timezone Europe/Warsaw)

  • Branch creation
    • Only on Sunday and Saturday (* * * * 0,6)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added dependencies Pull requests that update a dependency file renovate labels Nov 7, 2026
@renovate
renovate Bot requested a review from a team November 7, 2026 10:38
@renovate renovate Bot added the renovate label Nov 7, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file renovate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants