@react-x11/components 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/dist/code/index.d.ts.map +1 -1
  2. package/dist/code/index.js +25 -24
  3. package/dist/code/index.js.map +1 -1
  4. package/dist/code-language/index.d.ts +1 -1
  5. package/dist/code-language/index.d.ts.map +1 -1
  6. package/dist/code-language/index.js +1 -1
  7. package/dist/code-language/index.js.map +1 -1
  8. package/dist/code-language/runs.d.ts +31 -0
  9. package/dist/code-language/runs.d.ts.map +1 -1
  10. package/dist/code-language/runs.js +105 -0
  11. package/dist/code-language/runs.js.map +1 -1
  12. package/dist/codeblock/index.d.ts +13 -0
  13. package/dist/codeblock/index.d.ts.map +1 -1
  14. package/dist/codeblock/index.js +37 -1
  15. package/dist/codeblock/index.js.map +1 -1
  16. package/dist/flow/node.d.ts +14 -6
  17. package/dist/flow/node.d.ts.map +1 -1
  18. package/dist/flow/node.js +82 -64
  19. package/dist/flow/node.js.map +1 -1
  20. package/dist/html/controls.d.ts +26 -7
  21. package/dist/html/controls.d.ts.map +1 -1
  22. package/dist/html/controls.js +28 -3
  23. package/dist/html/controls.js.map +1 -1
  24. package/dist/html/css/cascade.d.ts +32 -10
  25. package/dist/html/css/cascade.d.ts.map +1 -1
  26. package/dist/html/css/cascade.js +89 -31
  27. package/dist/html/css/cascade.js.map +1 -1
  28. package/dist/html/css/color.d.ts +19 -0
  29. package/dist/html/css/color.d.ts.map +1 -1
  30. package/dist/html/css/color.js +86 -0
  31. package/dist/html/css/color.js.map +1 -1
  32. package/dist/html/css/parse.d.ts +11 -0
  33. package/dist/html/css/parse.d.ts.map +1 -1
  34. package/dist/html/css/parse.js +114 -4
  35. package/dist/html/css/parse.js.map +1 -1
  36. package/dist/html/css/style.d.ts +45 -5
  37. package/dist/html/css/style.d.ts.map +1 -1
  38. package/dist/html/css/style.js +363 -14
  39. package/dist/html/css/style.js.map +1 -1
  40. package/dist/html/css/ua.js +22 -5
  41. package/dist/html/css/ua.js.map +1 -1
  42. package/dist/html/css/values.d.ts +10 -1
  43. package/dist/html/css/values.d.ts.map +1 -1
  44. package/dist/html/css/values.js +27 -2
  45. package/dist/html/css/values.js.map +1 -1
  46. package/dist/html/css/vars.d.ts +5 -0
  47. package/dist/html/css/vars.d.ts.map +1 -1
  48. package/dist/html/css/vars.js +2 -2
  49. package/dist/html/css/vars.js.map +1 -1
  50. package/dist/html/dom.d.ts.map +1 -1
  51. package/dist/html/dom.js +35 -2
  52. package/dist/html/dom.js.map +1 -1
  53. package/dist/html/index.d.ts.map +1 -1
  54. package/dist/html/index.js +38 -1
  55. package/dist/html/index.js.map +1 -1
  56. package/dist/html/layout/block.d.ts +11 -2
  57. package/dist/html/layout/block.d.ts.map +1 -1
  58. package/dist/html/layout/block.js +306 -25
  59. package/dist/html/layout/block.js.map +1 -1
  60. package/dist/html/layout/boxes.d.ts +61 -6
  61. package/dist/html/layout/boxes.d.ts.map +1 -1
  62. package/dist/html/layout/boxes.js +65 -16
  63. package/dist/html/layout/boxes.js.map +1 -1
  64. package/dist/html/layout/cache.d.ts +2 -2
  65. package/dist/html/layout/cache.d.ts.map +1 -1
  66. package/dist/html/layout/cache.js +8 -3
  67. package/dist/html/layout/cache.js.map +1 -1
  68. package/dist/html/layout/floats.d.ts +4 -0
  69. package/dist/html/layout/floats.d.ts.map +1 -1
  70. package/dist/html/layout/floats.js +26 -0
  71. package/dist/html/layout/floats.js.map +1 -1
  72. package/dist/html/layout/inline.d.ts +29 -2
  73. package/dist/html/layout/inline.d.ts.map +1 -1
  74. package/dist/html/layout/inline.js +1454 -125
  75. package/dist/html/layout/inline.js.map +1 -1
  76. package/dist/html/node.d.ts +33 -0
  77. package/dist/html/node.d.ts.map +1 -1
  78. package/dist/html/node.js +608 -86
  79. package/dist/html/node.js.map +1 -1
  80. package/dist/html/paint.d.ts +53 -1
  81. package/dist/html/paint.d.ts.map +1 -1
  82. package/dist/html/paint.js +746 -214
  83. package/dist/html/paint.js.map +1 -1
  84. package/dist/html/surfaces.d.ts +7 -2
  85. package/dist/html/surfaces.d.ts.map +1 -1
  86. package/dist/html/surfaces.js +16 -0
  87. package/dist/html/surfaces.js.map +1 -1
  88. package/dist/html/svg.d.ts.map +1 -1
  89. package/dist/html/svg.js +27 -20
  90. package/dist/html/svg.js.map +1 -1
  91. package/dist/internal/codelines.d.ts +42 -0
  92. package/dist/internal/codelines.d.ts.map +1 -0
  93. package/dist/internal/codelines.js +170 -0
  94. package/dist/internal/codelines.js.map +1 -0
  95. package/dist/internal/window.d.ts +22 -0
  96. package/dist/internal/window.d.ts.map +1 -1
  97. package/dist/internal/window.js +35 -8
  98. package/dist/internal/window.js.map +1 -1
  99. package/dist/markdown/index.d.ts.map +1 -1
  100. package/dist/markdown/index.js +98 -26
  101. package/dist/markdown/index.js.map +1 -1
  102. package/dist/rich-text-editor/index.d.ts.map +1 -1
  103. package/dist/rich-text-editor/index.js +3 -8
  104. package/dist/rich-text-editor/index.js.map +1 -1
  105. package/dist/rich-text-editor/markdown.d.ts.map +1 -1
  106. package/dist/rich-text-editor/markdown.js +30 -1
  107. package/dist/rich-text-editor/markdown.js.map +1 -1
  108. package/dist/rich-text-editor/replace.d.ts +13 -0
  109. package/dist/rich-text-editor/replace.d.ts.map +1 -0
  110. package/dist/rich-text-editor/replace.js +64 -0
  111. package/dist/rich-text-editor/replace.js.map +1 -0
  112. package/dist/richtext/node.d.ts +7 -0
  113. package/dist/richtext/node.d.ts.map +1 -1
  114. package/dist/richtext/node.js.map +1 -1
  115. package/dist/terminal-output/index.d.ts.map +1 -1
  116. package/dist/terminal-output/index.js +100 -25
  117. package/dist/terminal-output/index.js.map +1 -1
  118. package/dist/terminal-output/runs.d.ts +4 -1
  119. package/dist/terminal-output/runs.d.ts.map +1 -1
  120. package/dist/terminal-output/runs.js +5 -1
  121. package/dist/terminal-output/runs.js.map +1 -1
  122. package/package.json +5 -3
  123. package/src/code/index.ts +34 -32
  124. package/src/code-language/index.ts +1 -1
  125. package/src/code-language/runs.ts +111 -1
  126. package/src/codeblock/index.ts +48 -1
  127. package/src/flow/node.ts +80 -64
  128. package/src/html/controls.ts +50 -9
  129. package/src/html/css/cascade.ts +134 -43
  130. package/src/html/css/color.ts +87 -0
  131. package/src/html/css/parse.ts +107 -4
  132. package/src/html/css/style.ts +386 -23
  133. package/src/html/css/ua.ts +22 -5
  134. package/src/html/css/values.ts +31 -3
  135. package/src/html/css/vars.ts +2 -2
  136. package/src/html/dom.ts +38 -2
  137. package/src/html/index.ts +39 -1
  138. package/src/html/layout/block.ts +360 -22
  139. package/src/html/layout/boxes.ts +98 -23
  140. package/src/html/layout/cache.ts +8 -3
  141. package/src/html/layout/floats.ts +24 -0
  142. package/src/html/layout/inline.ts +1690 -119
  143. package/src/html/node.ts +648 -101
  144. package/src/html/paint.ts +883 -283
  145. package/src/html/surfaces.ts +21 -1
  146. package/src/html/svg.ts +30 -19
  147. package/src/internal/codelines.ts +200 -0
  148. package/src/internal/window.ts +36 -8
  149. package/src/markdown/index.ts +145 -26
  150. package/src/rich-text-editor/index.ts +3 -11
  151. package/src/rich-text-editor/markdown.ts +36 -1
  152. package/src/rich-text-editor/replace.ts +85 -0
  153. package/src/richtext/node.ts +7 -0
  154. package/src/terminal-output/index.ts +127 -34
  155. package/src/terminal-output/runs.ts +16 -2
@@ -36,6 +36,7 @@ import type { ContentItem } from '../css/content.js';
36
36
  import {
37
37
  CONTAIN_STYLE,
38
38
  FIRST_LINE_INHERITED,
39
+ NO_MASK,
39
40
  copyStyle,
40
41
  firstLineParent,
41
42
  inherit,
@@ -187,6 +188,15 @@ export interface LineText {
187
188
  * spacer: a unit of the layout that is no text of the document's
188
189
  * (`documentOffsetOf`, `layoutOffsetOf`). */
189
190
  gaps?: number[];
191
+ /**
192
+ * The spaces `pre-wrap` keeps that this fragment's line ends on, which an
193
+ * engine strips from a line's end as though CSS removed them there: each
194
+ * one's offset in the layout's text and where it is, from the layout's
195
+ * origin, beside the line's end in logical order (`hangPreserved`). They
196
+ * are their inline box's, whose background and border cover them, and
197
+ * the ones before a forced break that fit take room on the line.
198
+ */
199
+ hung?: { at: number; x: number; width: number }[];
190
200
  /** Any offset in the layout's own text as a document index — how a run
191
201
  * under the pointer finds the element whose text it is. Per pass: the
192
202
  * layout may be one an earlier pass made (`TextLayoutCache`), and the
@@ -233,6 +243,10 @@ export interface TextLayoutLike {
233
243
  height: number;
234
244
  baseline: number;
235
245
  width: number;
246
+ /** Its width with the white space it ends on kept, in the item it
247
+ * ends: how far it moves the pen where text goes on after it on the
248
+ * same line. ntk's, from 8.17.0; an engine without it leaves it out. */
249
+ advance?: number;
236
250
  ascent: number;
237
251
  descent: number;
238
252
  start: number;
@@ -556,6 +570,14 @@ export const INLINE_OFFSETS = new WeakMap<Box, { x: number; y: number }>();
556
570
  export const TEXT_SHIFTS = new WeakMap<LineText, { x: number; y: number }>();
557
571
  export const SHIFTED_LINES = new WeakSet<LineBox>();
558
572
 
573
+ /** Of a block's lines, by the array they are, those `position: relative`
574
+ * or a translation moved something off — a text in a moved inline box, or
575
+ * an inline-block or an image on it — which is drawn where it went while
576
+ * the line stays where it was: what the paint's cull of a block's lines
577
+ * has to look at past the lines the damage meets (`paintLines`). By the
578
+ * array, so that a layout that makes new lines leaves none of the old. */
579
+ export const MOVED_OFF_LINES = new WeakMap<LineBox[], Set<LineBox>>();
580
+
559
581
  /** How far `vertical-align` raised a text above its line's baseline, and an
560
582
  * inline box's own baseline, where it did: beside the lines and the boxes
561
583
  * for the reason the offsets above are. A line holding a raised text is
@@ -573,6 +595,12 @@ export const BOX_RAISES = new WeakMap<Box, number>();
573
595
  * background, drawn from its baseline, is put there by line. */
574
596
  export const LINE_BOX_RAISES = new WeakMap<LineBox, Map<Box, number>>();
575
597
 
598
+ /** The face of an inline box with padding above or below its text and
599
+ * nothing to paint behind it, which has no `decoration`: its fragments
600
+ * still reach past its lines by the padding, and count in the scrollable
601
+ * overflow of the block they are in (`computePaintBounds`). */
602
+ export const PADDED_FACES = new WeakMap<Box, InlineDecoration>();
603
+
576
604
  /** The table cells wholly in columns `visibility: collapse` took out of
577
605
  * their table (CSS 2.1 17.5.5), which the paint pass leaves out: a cell is
578
606
  * no descendant of its column and inherits nothing from it, so its own
@@ -607,11 +635,17 @@ export const GRID_TRACKS = new WeakMap<Box, GridTracks>();
607
635
  * `order` moves any: an absolutely positioned child's is 0. */
608
636
  export const PAINT_ORDER = new WeakMap<Box, Box[]>();
609
637
 
610
- /** The blocks that broke a relatively positioned inline box in pieces,
611
- * under its first piece: its offset moves them too (CSS 2.1 9.2.1.1),
612
- * though they stand outside it (`breakAround`). */
638
+ /** The blocks that broke an inline box in pieces, under its first piece
639
+ * (`breakAround`): a relative offset of the box moves them too (CSS 2.1
640
+ * 9.2.1.1), though they stand outside it, and its rect takes them in, as
641
+ * a browser's does (`elementRect`). */
613
642
  export const CUT_BLOCKS = new WeakMap<Box, Box[]>();
614
643
 
644
+ /** The element a pseudo-element's box is generated from, which has no
645
+ * element of its own (`Box.pseudo`): whose the images its styles name are,
646
+ * when the host is asked for them. */
647
+ export const GENERATED_FROM = new WeakMap<Box, Element>();
648
+
615
649
  /** The blocks that broke an inline box under full opacity in pieces, and
616
650
  * the opacity they take from it — from each such inline box around them,
617
651
  * multiplied. They stand outside it (CSS 2.1 9.2.1.1) and are still its
@@ -639,9 +673,10 @@ export interface BoxTree {
639
673
  controls: Box[];
640
674
  /** Every box carrying an `href`, for click and hover. */
641
675
  links: Box[];
642
- /** Every element's box with a `background-image` or a border image,
643
- * for the host to be asked for: a document has a handful, and finding
644
- * them was a walk over every box after every build. */
676
+ /** Every box with a `background-image`, a border image or a mask image,
677
+ * an element's or a pseudo-element's, for the host to be asked for: a
678
+ * document has a handful, and finding them was a walk over every box
679
+ * after every build. */
645
680
  backgrounds: Box[];
646
681
  /** Every image generated content names, the element whose
647
682
  * pseudo-element names it, for the host to be asked for, and whether its
@@ -670,6 +705,11 @@ export interface BoxTree {
670
705
  /** Whether any box paints its background through its text
671
706
  * (`background-clip: text`): where none does, no paragraph looks. */
672
707
  clipText: boolean;
708
+ /** The style of the `<html>` a document with neither an `<html>` nor a
709
+ * `<body>` implies around the body the root box stands in for
710
+ * (`Cascade.rootStyle`), whose background is the canvas's; null where
711
+ * the document has either. */
712
+ impliedHtml: ComputedStyle | null;
673
713
  }
674
714
 
675
715
  export interface BuildOptions {
@@ -774,7 +814,10 @@ class Builder {
774
814
  run(root: Element): BoxTree {
775
815
  const cascade = this._options.cascade;
776
816
  cascade.beginSharing();
777
- const rootStyle = cascade.rootStyle(hasBody(root), hasHtml(root));
817
+ const { style: rootStyle, html: impliedHtml } = cascade.rootStyle(
818
+ hasBody(root),
819
+ hasHtml(root),
820
+ );
778
821
  const rootBox = new Box('block', null, rootStyle);
779
822
  // a fragment's root stands in for a `<body>`, counters and all
780
823
  this._scopes.open();
@@ -808,6 +851,7 @@ class Builder {
808
851
  nestedOutOfLine: this._nestedOutOfLine,
809
852
  movedInline: this._movedInline,
810
853
  clipText: this._clipText,
854
+ impliedHtml,
811
855
  };
812
856
  }
813
857
 
@@ -1008,13 +1052,7 @@ class Builder {
1008
1052
  this._firstLine = true;
1009
1053
  }
1010
1054
  }
1011
- if (
1012
- style.backgroundImage ||
1013
- style.backgroundImages ||
1014
- typeof style.borderImage.source === 'string'
1015
- ) {
1016
- this._backgrounds.push(box);
1017
- }
1055
+ if (namesImages(style)) this._backgrounds.push(box);
1018
1056
  if (style.position === 'absolute' || style.position === 'fixed')
1019
1057
  box.outOfFlow = true;
1020
1058
  else if (style.float !== 'none') box.isFloat = true;
@@ -1141,13 +1179,7 @@ class Builder {
1141
1179
  const box = new Box('replaced', el, style);
1142
1180
  box.replaced = replaced;
1143
1181
  into.append(box);
1144
- if (
1145
- style.backgroundImage ||
1146
- style.backgroundImages ||
1147
- typeof style.borderImage.source === 'string'
1148
- ) {
1149
- this._backgrounds.push(box);
1150
- }
1182
+ if (namesImages(style)) this._backgrounds.push(box);
1151
1183
  if (style.position === 'absolute' || style.position === 'fixed')
1152
1184
  box.outOfFlow = true;
1153
1185
  else if (style.float !== 'none') box.isFloat = true;
@@ -1278,6 +1310,10 @@ class Builder {
1278
1310
  const box = new Box(boxKindFor(style.display), null, style);
1279
1311
  box.pseudo = which;
1280
1312
  into.append(box);
1313
+ // its images are its element's to ask for: a `::after` with no content
1314
+ // but a background, which designs hang a picture on, drew nothing
1315
+ GENERATED_FROM.set(box, el);
1316
+ if (namesImages(style)) this._backgrounds.push(box);
1281
1317
  // a list item it generates has a marker as an element's has, of the
1282
1318
  // `list-item` counter it has just counted (CSS 2.1 12.5): outside it,
1283
1319
  // or at the start of its content
@@ -1697,6 +1733,10 @@ class Builder {
1697
1733
  const letterStyle = cascade.firstLetterStyle(search.rules, style);
1698
1734
  const box = new Box(boxKindFor(letterStyle.display), null, letterStyle);
1699
1735
  box.pseudo = 'first-letter';
1736
+ if (owner) {
1737
+ GENERATED_FROM.set(box, owner);
1738
+ if (namesImages(letterStyle)) this._backgrounds.push(box);
1739
+ }
1700
1740
  if (letterStyle.float !== 'none') {
1701
1741
  box.isFloat = true;
1702
1742
  if (into.kind === 'inline') this._nestedOutOfLine = true;
@@ -2017,6 +2057,30 @@ function transformText(
2017
2057
  }
2018
2058
  }
2019
2059
 
2060
+ /**
2061
+ * `text` transformed as `transform` says, where it stands for text laid out
2062
+ * already — a first line's, whose `::first-line` transforms it (CSS 2.1
2063
+ * 5.12.1): a character at a time where the transform would change its
2064
+ * length, which moves every offset after it — `ß` is `SS` in capitals —
2065
+ * and that character kept as it is.
2066
+ */
2067
+ export function transformInPlace(
2068
+ text: string,
2069
+ transform: ComputedStyle['textTransform'],
2070
+ lettered = false,
2071
+ ): string {
2072
+ const whole = transformText(text, transform, lettered);
2073
+ if (whole.length === text.length) return whole;
2074
+ let out = '';
2075
+ let state = lettered;
2076
+ for (const ch of text) {
2077
+ const one = transformText(ch, transform, state);
2078
+ out += one.length === ch.length ? one : ch;
2079
+ state = letteredAfter(ch, state);
2080
+ }
2081
+ return out;
2082
+ }
2083
+
2020
2084
  /** A letter or a number: what a word's first typographic letter unit is
2021
2085
  * (CSS Text 3, 2.1). */
2022
2086
  const LETTER_UNIT = /[\p{L}\p{N}]/u;
@@ -2089,7 +2153,7 @@ function titleCase(ch: string): string {
2089
2153
  * nothing but joining punctuation leaves it as it was. Asked of every text,
2090
2154
  * from the end, where it is almost always decided by the last character.
2091
2155
  */
2092
- function letteredAfter(text: string, lettered: boolean): boolean {
2156
+ export function letteredAfter(text: string, lettered: boolean): boolean {
2093
2157
  for (let i = text.length - 1; i >= 0; i -= 1) {
2094
2158
  const c = text.charCodeAt(i);
2095
2159
  if (c < 0x80) {
@@ -2567,7 +2631,7 @@ function breakAround(inline: Box): Box[] | null {
2567
2631
  for (let i = 0; i < pieces.length; i += 1) {
2568
2632
  pieces[i].cut = (i > 0 ? 1 : 0) | (i < pieces.length - 1 ? 2 : 0);
2569
2633
  }
2570
- if (isRelative(inline.style)) CUT_BLOCKS.set(pieces[0], blocks);
2634
+ CUT_BLOCKS.set(pieces[0], blocks);
2571
2635
  const fade = inline.style.opacity;
2572
2636
  if (fade < 1) {
2573
2637
  for (const block of blocks) {
@@ -2577,6 +2641,17 @@ function breakAround(inline: Box): Box[] | null {
2577
2641
  return out;
2578
2642
  }
2579
2643
 
2644
+ /** Whether a style names an image for its box to be drawn with: a
2645
+ * background's, a border's, or a mask's. */
2646
+ function namesImages(style: ComputedStyle): boolean {
2647
+ return (
2648
+ !!style.backgroundImage ||
2649
+ !!style.backgroundImages ||
2650
+ typeof style.borderImage.source === 'string' ||
2651
+ style.mask !== NO_MASK
2652
+ );
2653
+ }
2654
+
2580
2655
  /**
2581
2656
  * The style of an anonymous box inside a parent: what the parent passes on
2582
2657
  * by inheritance, and every other property at its initial value, as CSS 2.1
@@ -190,6 +190,7 @@ export const RUN_FIELDS = [
190
190
  'features',
191
191
  'nowrap',
192
192
  'shapeApart',
193
+ 'kernAcross',
193
194
  ] as const satisfies readonly (keyof TextRun)[];
194
195
 
195
196
  /** A field of `TextRun` missing from `RUN_FIELDS` names itself here. */
@@ -223,7 +224,8 @@ function sameRun(a: TextRun, b: TextRun): boolean {
223
224
  a.href === b.href &&
224
225
  a.features === b.features &&
225
226
  a.nowrap === b.nowrap &&
226
- a.shapeApart === b.shapeApart
227
+ a.shapeApart === b.shapeApart &&
228
+ a.kernAcross === b.kernAcross
227
229
  );
228
230
  }
229
231
 
@@ -250,7 +252,8 @@ function sameStyle(
250
252
  a.href === b.href &&
251
253
  a.features === b.features &&
252
254
  a.nowrap === b.nowrap &&
253
- a.shapeApart === b.shapeApart
255
+ a.shapeApart === b.shapeApart &&
256
+ a.kernAcross === b.kernAcross
254
257
  );
255
258
  }
256
259
 
@@ -265,6 +268,7 @@ export const OPTION_FIELDS = [
265
268
  'overflow',
266
269
  'overflowWrap',
267
270
  'wrap',
271
+ 'fit',
268
272
  ] as const satisfies readonly (keyof Options)[];
269
273
 
270
274
  /** An option missing from `OPTION_FIELDS` names itself here. */
@@ -284,6 +288,7 @@ function sameOptions(a: Options, b: Options): boolean {
284
288
  a.maxLines === b.maxLines &&
285
289
  a.overflow === b.overflow &&
286
290
  a.overflowWrap === b.overflowWrap &&
287
- a.wrap === b.wrap
291
+ a.wrap === b.wrap &&
292
+ a.fit === b.fit
288
293
  );
289
294
  }
@@ -153,6 +153,30 @@ export class FloatContext {
153
153
  return lowest;
154
154
  }
155
155
 
156
+ /** Move the floats placed since `mark` down by `dy`, with the block they
157
+ * were placed in: a list item's first block goes lower to make room
158
+ * for its marker once it is laid out (`layoutChildren`). */
159
+ moveSince(mark: number, dy: number): void {
160
+ if (!dy || mark >= this._boxes.length) return;
161
+ for (let i = mark; i < this._boxes.length; i += 1) {
162
+ const float = this._boxes[i];
163
+ this._boxes[i] = {
164
+ ...float,
165
+ top: float.top + dy,
166
+ bottom: float.bottom + dy,
167
+ };
168
+ }
169
+ this._lowestLeft = -Infinity;
170
+ this._lowestRight = -Infinity;
171
+ this._lastTop = -Infinity;
172
+ for (const float of this._boxes) {
173
+ if (float.top > this._lastTop) this._lastTop = float.top;
174
+ if (float.side === 'left')
175
+ this._lowestLeft = Math.max(this._lowestLeft, float.bottom);
176
+ else this._lowestRight = Math.max(this._lowestRight, float.bottom);
177
+ }
178
+ }
179
+
156
180
  /** How far down the floats reach — what a container that establishes a
157
181
  * BFC has to grow to, so it does not end above its own floats. */
158
182
  get bottom(): number {