@react-x11/components 0.14.1 → 0.16.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.
- package/dist/code-editor/node.d.ts +13 -0
- package/dist/code-editor/node.d.ts.map +1 -1
- package/dist/code-editor/node.js +23 -5
- package/dist/code-editor/node.js.map +1 -1
- package/dist/html/css/cascade.d.ts +171 -26
- package/dist/html/css/cascade.d.ts.map +1 -1
- package/dist/html/css/cascade.js +616 -216
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/color.d.ts +25 -0
- package/dist/html/css/color.d.ts.map +1 -1
- package/dist/html/css/color.js +307 -19
- package/dist/html/css/color.js.map +1 -1
- package/dist/html/css/content.d.ts +11 -6
- package/dist/html/css/content.d.ts.map +1 -1
- package/dist/html/css/content.js +171 -12
- package/dist/html/css/content.js.map +1 -1
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +62 -9
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/shapes.d.ts +18 -0
- package/dist/html/css/shapes.d.ts.map +1 -1
- package/dist/html/css/shapes.js +21 -1
- package/dist/html/css/shapes.js.map +1 -1
- package/dist/html/css/style.d.ts +42 -5
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +74 -12
- package/dist/html/css/style.js.map +1 -1
- package/dist/html/css/ua.js +15 -0
- package/dist/html/css/ua.js.map +1 -1
- package/dist/html/css/values.d.ts +5 -0
- package/dist/html/css/values.d.ts.map +1 -1
- package/dist/html/css/values.js +18 -9
- package/dist/html/css/values.js.map +1 -1
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +7 -0
- package/dist/html/index.js.map +1 -1
- package/dist/html/layout/block.d.ts +29 -9
- package/dist/html/layout/block.d.ts.map +1 -1
- package/dist/html/layout/block.js +141 -52
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +16 -2
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +144 -23
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/css-grid.d.ts.map +1 -1
- package/dist/html/layout/css-grid.js +11 -9
- package/dist/html/layout/css-grid.js.map +1 -1
- package/dist/html/layout/flex.d.ts.map +1 -1
- package/dist/html/layout/flex.js +1631 -221
- package/dist/html/layout/flex.js.map +1 -1
- package/dist/html/layout/inline.d.ts +15 -3
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +23 -8
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/layout/table.d.ts +27 -1
- package/dist/html/layout/table.d.ts.map +1 -1
- package/dist/html/layout/table.js +886 -324
- package/dist/html/layout/table.js.map +1 -1
- package/dist/html/node.d.ts +35 -4
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +118 -26
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +558 -178
- package/dist/html/paint.js.map +1 -1
- package/dist/html/resources.js +14 -1
- package/dist/html/resources.js.map +1 -1
- package/dist/html/svg.d.ts +23 -7
- package/dist/html/svg.d.ts.map +1 -1
- package/dist/html/svg.js +264 -59
- package/dist/html/svg.js.map +1 -1
- package/dist/html/widgets.d.ts.map +1 -1
- package/dist/html/widgets.js +57 -4
- package/dist/html/widgets.js.map +1 -1
- package/package.json +3 -3
- package/src/code-editor/node.ts +24 -5
- package/src/html/css/cascade.ts +697 -221
- package/src/html/css/color.ts +345 -18
- package/src/html/css/content.ts +173 -15
- package/src/html/css/parse.ts +60 -8
- package/src/html/css/shapes.ts +35 -1
- package/src/html/css/style.ts +122 -17
- package/src/html/css/ua.ts +15 -0
- package/src/html/css/values.ts +23 -9
- package/src/html/index.ts +7 -0
- package/src/html/layout/block.ts +149 -58
- package/src/html/layout/boxes.ts +171 -27
- package/src/html/layout/css-grid.ts +12 -9
- package/src/html/layout/flex.ts +1843 -212
- package/src/html/layout/inline.ts +27 -7
- package/src/html/layout/table.ts +961 -332
- package/src/html/node.ts +151 -27
- package/src/html/paint.ts +692 -234
- package/src/html/resources.ts +13 -1
- package/src/html/svg.ts +299 -56
- package/src/html/widgets.ts +61 -4
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
// inline pass ask "how wide is the line at this y" without knowing whose
|
|
12
12
|
// formatting context it is inside.
|
|
13
13
|
import { AUTO, gapOf, isPct, isTransparent, resolve, resolveOrNull, } from '../css/values.js';
|
|
14
|
-
import { CONTAIN_INLINE_SIZE, CONTAIN_LAYOUT, CONTAIN_PAINT, CONTAIN_SIZE, scrolls, } from '../css/style.js';
|
|
14
|
+
import { CONTAIN_INLINE_SIZE, CONTAIN_LAYOUT, CONTAIN_PAINT, CONTAIN_SIZE, INLINE_BEFORE_ABSOLUTE, scrolls, } from '../css/style.js';
|
|
15
15
|
import { about, linearOf, matrixOf, transformed } from '../css/transform.js';
|
|
16
16
|
import { lineOf, spanToName } from './grid-lines.js';
|
|
17
17
|
import { columnsOf, forgetColumns, layoutColumns, spansColumns, } from './multicol.js';
|
|
18
18
|
import { BOX_RAISES, Box, CLAMPED, CLEARED_FROM, COLUMN_PIECES, CUT_BLOCKS, GRID_TRACKS, FIRST_LINE, INLINE_OFFSETS, MOVED_OFF_LINES, LINE_BOX_RAISES, SHIFTED_LINES, TEXT_SHIFTS, columned, isBlank, } from './boxes.js';
|
|
19
19
|
import { FloatContext } from './floats.js';
|
|
20
|
-
import { faceExtentOf, isButton, joinsBefore, layoutInline, lineHeightMultiplier, spaceBreaksOnly, strutOf, widestWord, } from './inline.js';
|
|
20
|
+
import { emptyLinePoint, faceExtentOf, isButton, joinsBefore, layoutInline, lineHeightMultiplier, spaceBreaksOnly, strutOf, widestWord, } from './inline.js';
|
|
21
21
|
import { layoutFlex } from './flex.js';
|
|
22
|
-
import { finishCaptions, layoutTable } from './table.js';
|
|
22
|
+
import { finishCaptions, givenHeight, layoutTable } from './table.js';
|
|
23
23
|
import { collapseEdges } from './collapse.js';
|
|
24
24
|
import { clipsFor, computePaintBounds, FIXED_BOXES, fixedToViewport, hoistNegative, OUT_OF_FLOW_REACH, stackLayers, } from '../paint.js';
|
|
25
25
|
/** Lay the whole document out at a width. */
|
|
@@ -622,7 +622,16 @@ function layoutChildren(box, ctx, floats, contentTop, contentWidth, leading = 0)
|
|
|
622
622
|
marked = null;
|
|
623
623
|
}
|
|
624
624
|
if (child.outOfFlow) {
|
|
625
|
-
|
|
625
|
+
const top = y + marginOf(pendingMargin);
|
|
626
|
+
if (INLINE_BEFORE_ABSOLUTE.has(child.style)) {
|
|
627
|
+
// one that was inline-level is on a line of its own, beside the
|
|
628
|
+
// floats there, where the line's alignment puts what it holds
|
|
629
|
+
const band = floats.bandAt(top, 1, contentLeft, contentLeft + contentWidth);
|
|
630
|
+
const at = emptyLinePoint(box.style, band.left, band.right);
|
|
631
|
+
placeStatic(child, box, at, 0, top);
|
|
632
|
+
}
|
|
633
|
+
else
|
|
634
|
+
placeStatic(child, box, contentLeft, contentWidth, top);
|
|
626
635
|
ctx.positioned.push({
|
|
627
636
|
box: child,
|
|
628
637
|
containing: containingBlockFor(child) ?? box,
|
|
@@ -1327,38 +1336,61 @@ export const MIN_CONTENT_PROBE = 0;
|
|
|
1327
1336
|
* a cell set to 10% measured no wider than its padding.
|
|
1328
1337
|
*/
|
|
1329
1338
|
export function measureIntrinsicWidth(box, ctx, available, content = false) {
|
|
1330
|
-
ctx.layoutSubtree
|
|
1339
|
+
// not through `ctx.layoutSubtree`, which is this and one frame more on
|
|
1340
|
+
// the stack for every level of a document that measures what it holds
|
|
1341
|
+
// (`layoutTable`)
|
|
1342
|
+
layoutSubtree(box, ctx, available, undefined, true);
|
|
1331
1343
|
const specified = box.style.width;
|
|
1332
1344
|
if (!content && specified !== AUTO && Number.isFinite(box.width)) {
|
|
1333
1345
|
return box.width;
|
|
1334
1346
|
}
|
|
1335
|
-
return intrinsicWidth(box) +
|
|
1347
|
+
return (intrinsicWidth(box, undefined, available === MIN_CONTENT_PROBE) +
|
|
1348
|
+
box.horizontalExtra);
|
|
1336
1349
|
}
|
|
1337
1350
|
/**
|
|
1338
1351
|
* Lay a box and everything under it out at a width, at the origin — what
|
|
1339
|
-
* `LayoutContext.layoutSubtree` hands to `flex.ts` and `
|
|
1340
|
-
* the shrink-to-fit probe
|
|
1341
|
-
* because there is nothing inside it to lay out.
|
|
1352
|
+
* `LayoutContext.layoutSubtree` hands to `flex.ts` and `css-grid.ts`, and
|
|
1353
|
+
* what the shrink-to-fit probe and a table's cells use. A replaced box is
|
|
1354
|
+
* sized rather than laid out, because there is nothing inside it to lay out.
|
|
1342
1355
|
*/
|
|
1343
|
-
function layoutSubtree(box, ctx, width,
|
|
1356
|
+
export function layoutSubtree(box, ctx, width,
|
|
1344
1357
|
/** Its containing block's width, where `width` is the box's own. */
|
|
1345
|
-
containing
|
|
1346
|
-
|
|
1358
|
+
containing,
|
|
1359
|
+
/** Whether this lays it out to measure it (`measureIntrinsicWidth`). */
|
|
1360
|
+
measuring = false) {
|
|
1361
|
+
const base = containing ?? width;
|
|
1362
|
+
resolveEdges(box, Number.isFinite(base) ? base : 0);
|
|
1347
1363
|
if (box.kind === 'replaced') {
|
|
1348
1364
|
sizeReplaced(box, width);
|
|
1349
1365
|
box.x = 0;
|
|
1350
1366
|
box.y = 0;
|
|
1351
1367
|
return;
|
|
1352
1368
|
}
|
|
1353
|
-
//
|
|
1369
|
+
// Within its limits, a percentage among them of its containing block's
|
|
1354
1370
|
// width and not of its own: a flex item `max-width: 50%` that the flex
|
|
1355
|
-
// layout made half its row was laid out at a quarter of it.
|
|
1356
|
-
//
|
|
1357
|
-
//
|
|
1358
|
-
//
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1371
|
+
// layout made half its row was laid out at a quarter of it. An
|
|
1372
|
+
// intrinsic limit is among them, as it is in a block's flow: without it,
|
|
1373
|
+
// a flex or grid item `min-width: max-content` that its layout made as
|
|
1374
|
+
// wide as its content was laid out at a smaller `max-width`, where the
|
|
1375
|
+
// minimum wins (CSS Sizing 3, 3.1). Not where the box is laid out to be
|
|
1376
|
+
// measured, since that is what an intrinsic limit is measured from.
|
|
1377
|
+
//
|
|
1378
|
+
// A table cell laid out in its columns, which hand it its row's width,
|
|
1379
|
+
// is as wide as they are (CSS Tables 3, 3.10.2): its limits are theirs
|
|
1380
|
+
// to weigh (3.8.2), and have been. Clamped again, `td { max-width:
|
|
1381
|
+
// 50px }` in a column 200 wide set its text in 50 of it. Probed for
|
|
1382
|
+
// what it asks of them, at none, it keeps within its length limits as
|
|
1383
|
+
// any box does; a percentage one is of nothing and does not hold it.
|
|
1384
|
+
let borderBox = Infinity;
|
|
1385
|
+
if (Number.isFinite(width)) {
|
|
1386
|
+
if (box.kind !== 'table-cell') {
|
|
1387
|
+
borderBox = clampWidth(box, width, base, measuring ? undefined : ctx);
|
|
1388
|
+
}
|
|
1389
|
+
else if (containing !== undefined)
|
|
1390
|
+
borderBox = width;
|
|
1391
|
+
else
|
|
1392
|
+
borderBox = clampWidth(box, width, NaN);
|
|
1393
|
+
}
|
|
1362
1394
|
layoutInternals(box, ctx, borderBox, 0, 0);
|
|
1363
1395
|
}
|
|
1364
1396
|
/**
|
|
@@ -1704,12 +1736,12 @@ function layoutMarker(box, marker, ctx) {
|
|
|
1704
1736
|
const style = box.style;
|
|
1705
1737
|
if (marker.image) {
|
|
1706
1738
|
// an image: its bottom on the first line's baseline, as an inline
|
|
1707
|
-
// image's is, and
|
|
1739
|
+
// image's is, and its own gap before the content (`MARKER_IMAGE_GAP`)
|
|
1708
1740
|
const first = firstLineIn(box);
|
|
1709
1741
|
marker.y = first
|
|
1710
1742
|
? first.y + first.baseline - marker.image.height
|
|
1711
1743
|
: box.contentY;
|
|
1712
|
-
const gap =
|
|
1744
|
+
const { gap } = marker.image;
|
|
1713
1745
|
// at the start of the line, which is its right in a right-to-left item
|
|
1714
1746
|
marker.x =
|
|
1715
1747
|
style.direction === 'rtl'
|
|
@@ -1743,8 +1775,13 @@ function layoutMarker(box, marker, ctx) {
|
|
|
1743
1775
|
});
|
|
1744
1776
|
marker.layout = layout;
|
|
1745
1777
|
// a space between it and the content — the one its style's suffix ends
|
|
1746
|
-
// in, or its own text's — in its own face: a line measures without
|
|
1747
|
-
|
|
1778
|
+
// in, or its own text's — in its own face: a line measures without the
|
|
1779
|
+
// spaces it ends in, and with a no-break space, which `content: "1.\a0"`
|
|
1780
|
+
// writes and which was a second gap on top of its own
|
|
1781
|
+
const trailing = marker.flush
|
|
1782
|
+
? (/[ \t\n\r\f]*$/.exec(marker.text)?.[0].length ?? 0)
|
|
1783
|
+
: 1;
|
|
1784
|
+
const gap = trailing ? trailing * markerGap(fonts, face) : 0;
|
|
1748
1785
|
// The marker sits on the first line of the item's *content*, which is not
|
|
1749
1786
|
// always the item's own: an `<li>` holding a paragraph, or one holding text
|
|
1750
1787
|
// and a nested list, has its inline content in an anonymous block. Looking
|
|
@@ -1918,13 +1955,16 @@ export const FLEXED_HEIGHT = new WeakMap();
|
|
|
1918
1955
|
*/
|
|
1919
1956
|
export const USED_HEIGHT = new WeakMap();
|
|
1920
1957
|
/**
|
|
1921
|
-
* A table a grid
|
|
1922
|
-
* one it is laid out at. `normal` stretches any grid item but a
|
|
1923
|
-
* one (CSS Grid 1, 6.2), a
|
|
1924
|
-
*
|
|
1925
|
-
*
|
|
1926
|
-
*
|
|
1927
|
-
*
|
|
1958
|
+
* A table a grid or a flex layout gives its width, whose `auto` width is
|
|
1959
|
+
* then the one it is laid out at. `normal` stretches any grid item but a
|
|
1960
|
+
* replaced one across its area (CSS Grid 1, 6.2), and a flex item across a
|
|
1961
|
+
* column's line (CSS Flexbox 9.4, step 11), a table among them; and a flex
|
|
1962
|
+
* item along a row is the size the line flexed it to (9.7) — where in a
|
|
1963
|
+
* block's flow a table's `auto` width is its columns' (CSS 2.1 17.5.2;
|
|
1964
|
+
* Blink leaves tables out of the boxes a block stretches, `space_utils.cc`,
|
|
1965
|
+
* and stretches them in a grid, `grid_item.cc`, and a flex box). Set by
|
|
1966
|
+
* `css-grid.ts` and `flex.ts` for the item's own layout alone, and never
|
|
1967
|
+
* while its widths are measured.
|
|
1928
1968
|
*/
|
|
1929
1969
|
export const STRETCHED_ACROSS = new WeakSet();
|
|
1930
1970
|
/**
|
|
@@ -2092,6 +2132,14 @@ function finishHeight(box, contentHeight) {
|
|
|
2092
2132
|
if (box.kind === 'table-cell') {
|
|
2093
2133
|
CELL_CONTENT.set(box, contentHeight + box.verticalExtra);
|
|
2094
2134
|
}
|
|
2135
|
+
// A table a flex or grid layout gave a height is as tall as that, or as
|
|
2136
|
+
// its rows where they need more, which `layoutTable` has shared it out
|
|
2137
|
+
// among — whatever height it has of its own, which the flex layout
|
|
2138
|
+
// started from (`layoutTable`)
|
|
2139
|
+
if (box.kind === 'table' && Number.isFinite(givenHeight(box))) {
|
|
2140
|
+
box.height = contentHeight + box.verticalExtra;
|
|
2141
|
+
return;
|
|
2142
|
+
}
|
|
2095
2143
|
const set = specifiedHeight(box);
|
|
2096
2144
|
// at least zero: a `calc()` may come to less
|
|
2097
2145
|
const specified = set === null ? null : Math.max(0, set);
|
|
@@ -2146,7 +2194,9 @@ export function clampHeight(box, height) {
|
|
|
2146
2194
|
out = Math.min(out, max + (box.style.boxSizing === 'border-box' ? 0 : box.verticalExtra));
|
|
2147
2195
|
if (min !== null)
|
|
2148
2196
|
out = Math.max(out, min + (box.style.boxSizing === 'border-box' ? 0 : box.verticalExtra));
|
|
2149
|
-
|
|
2197
|
+
// no shorter than its padding and borders, as `clampWidth` is no
|
|
2198
|
+
// narrower
|
|
2199
|
+
return Math.max(box.verticalExtra, out);
|
|
2150
2200
|
}
|
|
2151
2201
|
/** Place a block-level box horizontally, honouring `margin: auto`. */
|
|
2152
2202
|
function placeBlock(box, contentLeft, y, containingWidth) {
|
|
@@ -2335,7 +2385,10 @@ room = containingWidth) {
|
|
|
2335
2385
|
if (style.minWidthKeyword && ctx) {
|
|
2336
2386
|
out = Math.max(out, keywordWidth(box, ctx, style.minWidthKeyword, containingWidth, room));
|
|
2337
2387
|
}
|
|
2338
|
-
|
|
2388
|
+
// and no narrower than its padding and borders: a `border-box` length
|
|
2389
|
+
// less than them leaves its content box none wide, and not less (CSS
|
|
2390
|
+
// Sizing 3, 3.3)
|
|
2391
|
+
return Math.max(box.horizontalExtra, out);
|
|
2339
2392
|
}
|
|
2340
2393
|
/** An intrinsic `min-width` or `max-width` in the room a box's margins
|
|
2341
2394
|
* leave it. Apart from `clampWidth`, which every block is sized through,
|
|
@@ -2365,21 +2418,25 @@ export function contentSizedWidth(box, ctx, size, available, percentBase) {
|
|
|
2365
2418
|
// the content's sizes, whatever width the box has of its own: a
|
|
2366
2419
|
// `min-width: max-content` beside a `width` is its content's widest,
|
|
2367
2420
|
// and a probe of the box at no width answered the probe's width
|
|
2368
|
-
let probed = false;
|
|
2369
2421
|
if (box.intrinsicMaxContent < 0) {
|
|
2370
2422
|
box.intrinsicMaxContent = measureIntrinsicWidth(box, ctx, Infinity, true);
|
|
2371
|
-
probed = true;
|
|
2372
2423
|
}
|
|
2373
2424
|
if (size !== 'max-content' && box.intrinsicMinContent < 0) {
|
|
2374
2425
|
box.intrinsicMinContent = measureIntrinsicWidth(box, ctx, MIN_CONTENT_PROBE, true);
|
|
2375
|
-
probed = true;
|
|
2376
2426
|
}
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2427
|
+
// The probes resolved a percentage of the box's padding or border
|
|
2428
|
+
// against nothing, which is how the sizes are kept, whatever the width
|
|
2429
|
+
// around the box: what one comes to against `percentBase` goes on top.
|
|
2430
|
+
// Left out, `width: max-content; padding-left: 10%` was as wide as its
|
|
2431
|
+
// content, the padding inside it.
|
|
2432
|
+
resolveEdges(box, 0);
|
|
2433
|
+
const bare = box.horizontalExtra;
|
|
2434
|
+
resolveEdges(box, Number.isFinite(percentBase) ? percentBase : 0);
|
|
2435
|
+
const extra = box.horizontalExtra - bare;
|
|
2436
|
+
const max = box.intrinsicMaxContent + extra;
|
|
2380
2437
|
if (size === 'max-content')
|
|
2381
2438
|
return max;
|
|
2382
|
-
const min = box.intrinsicMinContent;
|
|
2439
|
+
const min = box.intrinsicMinContent + extra;
|
|
2383
2440
|
if (size === 'min-content')
|
|
2384
2441
|
return min;
|
|
2385
2442
|
return Math.min(max, Math.max(min, fitRoom(box, size, available, percentBase)));
|
|
@@ -2506,6 +2563,11 @@ const PREFERRED = new WeakMap();
|
|
|
2506
2563
|
* or is indented, a block with widths of its own.
|
|
2507
2564
|
*/
|
|
2508
2565
|
export function exactMinContent(box, fonts) {
|
|
2566
|
+
// a flex row's is its items' side by side, a grid's its columns', and a
|
|
2567
|
+
// replaced element has no words: read as its widest word, a row of two
|
|
2568
|
+
// in a flex column's item was as narrow as the wider of them
|
|
2569
|
+
if (box.kind !== 'block' && box.kind !== 'table-cell')
|
|
2570
|
+
return null;
|
|
2509
2571
|
if (hasWidths(box.style) || contained(box, CONTAIN_WIDTH))
|
|
2510
2572
|
return null;
|
|
2511
2573
|
const inner = exactWords(box, fonts);
|
|
@@ -2643,8 +2705,13 @@ function wordBound(box, fonts, measured) {
|
|
|
2643
2705
|
* `seen.cut` is set where a line it measured was cut short by
|
|
2644
2706
|
* `text-overflow`, in a box with a width to cut it at: the line is wider
|
|
2645
2707
|
* than it was drawn, and the answer is of what was drawn.
|
|
2708
|
+
*
|
|
2709
|
+
* `narrowest` says the box was laid out by the min-content probe
|
|
2710
|
+
* (`MIN_CONTENT_PROBE`), and the answer is its min-content width: the
|
|
2711
|
+
* probe lays a box out at no width, but one with a least width of its own
|
|
2712
|
+
* at that, and nothing in the layout tells the two apart.
|
|
2646
2713
|
*/
|
|
2647
|
-
export function intrinsicWidth(box, seen) {
|
|
2714
|
+
export function intrinsicWidth(box, seen, narrowest = false) {
|
|
2648
2715
|
// under size containment, as though it held nothing: the size
|
|
2649
2716
|
// `contain-intrinsic-size` gives it, or none (CSS Containment 2, 3.2)
|
|
2650
2717
|
if (contained(box, CONTAIN_WIDTH)) {
|
|
@@ -2677,10 +2744,16 @@ export function intrinsicWidth(box, seen) {
|
|
|
2677
2744
|
}
|
|
2678
2745
|
let widest = 0;
|
|
2679
2746
|
// A row of flex items is as wide as all of them side by side, and gaps
|
|
2680
|
-
// between them; any other box is as wide as the widest thing in it
|
|
2747
|
+
// between them; any other box is as wide as the widest thing in it. So
|
|
2748
|
+
// is a row that wraps, at its narrowest: each of its items may be a line
|
|
2749
|
+
// of its own, and it is as wide as the widest of them (CSS Flexbox
|
|
2750
|
+
// 9.9.1). Summed, a wrapping row of three 30px items made a
|
|
2751
|
+
// `width: min-content` box around it 90 wide, the items side by side,
|
|
2752
|
+
// where Chrome has 30, one under another
|
|
2681
2753
|
const display = box.style.display;
|
|
2682
2754
|
const row = (display === 'flex' || display === 'inline-flex') &&
|
|
2683
2755
|
box.style.flexDirection.startsWith('row');
|
|
2756
|
+
const wraps = row && narrowest && box.style.flexWrap !== 'nowrap';
|
|
2684
2757
|
let total = 0;
|
|
2685
2758
|
let items = 0;
|
|
2686
2759
|
const lines = box.lines;
|
|
@@ -2749,7 +2822,7 @@ export function intrinsicWidth(box, seen) {
|
|
|
2749
2822
|
}
|
|
2750
2823
|
}
|
|
2751
2824
|
else {
|
|
2752
|
-
let inner = intrinsicWidth(child, seen) + child.horizontalExtra;
|
|
2825
|
+
let inner = intrinsicWidth(child, seen, narrowest) + child.horizontalExtra;
|
|
2753
2826
|
if (typeof style.maxWidth === 'number') {
|
|
2754
2827
|
inner = Math.min(inner, style.maxWidth + contentExtra(child));
|
|
2755
2828
|
}
|
|
@@ -2762,11 +2835,11 @@ export function intrinsicWidth(box, seen) {
|
|
|
2762
2835
|
across = Math.max(across, contribution);
|
|
2763
2836
|
continue;
|
|
2764
2837
|
}
|
|
2765
|
-
if (row) {
|
|
2838
|
+
if (row && !wraps) {
|
|
2766
2839
|
total += contribution;
|
|
2767
2840
|
items += 1;
|
|
2768
2841
|
}
|
|
2769
|
-
else if (!sideBySide)
|
|
2842
|
+
else if (wraps || !sideBySide)
|
|
2770
2843
|
widest = Math.max(widest, contribution);
|
|
2771
2844
|
else if (child.isFloat) {
|
|
2772
2845
|
const clear = style.clear;
|
|
@@ -2886,7 +2959,17 @@ stretchRoom = containingWidth) {
|
|
|
2886
2959
|
const ih = own.missing & 2 ? null : own.height;
|
|
2887
2960
|
// `aspect-ratio` over its own, unless written `auto` and it has one
|
|
2888
2961
|
const aspect = style.aspectRatio;
|
|
2889
|
-
const
|
|
2962
|
+
const pages = aspect !== null && !(aspect.auto && own.ratio > 0);
|
|
2963
|
+
const ratio = pages ? aspect.ratio : own.ratio;
|
|
2964
|
+
// A ratio of the page's is of the box `box-sizing` names (CSS Sizing 4,
|
|
2965
|
+
// 5.1): one axis's content size to the other's goes through the border
|
|
2966
|
+
// box there. Written with `auto`, it is of the content box, as the
|
|
2967
|
+
// replaced element's own is, whichever it is.
|
|
2968
|
+
const outer = pages && !aspect.auto && style.boxSizing === 'border-box';
|
|
2969
|
+
const ox = outer ? box.horizontalExtra : 0;
|
|
2970
|
+
const oy = outer ? box.verticalExtra : 0;
|
|
2971
|
+
const widthOf = (h) => Math.max(0, (h + oy) * ratio - ox);
|
|
2972
|
+
const heightOf = (w) => Math.max(0, (w + ox) / ratio - oy);
|
|
2890
2973
|
// the width a block would have here: what a ratio with no size fills, and
|
|
2891
2974
|
// an `hr`, whose whole appearance is its border across the line
|
|
2892
2975
|
const room = () => {
|
|
@@ -2900,18 +2983,18 @@ stretchRoom = containingWidth) {
|
|
|
2900
2983
|
// which moves both axes together
|
|
2901
2984
|
if (iw !== null) {
|
|
2902
2985
|
w = iw;
|
|
2903
|
-
h = ih ?? iw
|
|
2986
|
+
h = ih ?? heightOf(iw);
|
|
2904
2987
|
}
|
|
2905
2988
|
else if (ih !== null) {
|
|
2906
2989
|
h = ih;
|
|
2907
|
-
w = ih
|
|
2990
|
+
w = widthOf(ih);
|
|
2908
2991
|
}
|
|
2909
2992
|
else {
|
|
2910
2993
|
// a ratio and no size: CSS 2.1 leaves it undefined and suggests the
|
|
2911
2994
|
// width a block would have, which is what browsers do — or, where the
|
|
2912
2995
|
// containing block waits on this box, the default object size
|
|
2913
2996
|
w = Number.isFinite(containingWidth) ? room() : own.width;
|
|
2914
|
-
h = w
|
|
2997
|
+
h = heightOf(w);
|
|
2915
2998
|
}
|
|
2916
2999
|
[w, h] = constrained(w, h, minW, maxW, minH, maxH);
|
|
2917
3000
|
}
|
|
@@ -2923,7 +3006,7 @@ stretchRoom = containingWidth) {
|
|
|
2923
3006
|
if (width !== null)
|
|
2924
3007
|
w = width;
|
|
2925
3008
|
else if (usedHeight !== null && ratio > 0)
|
|
2926
|
-
w = usedHeight
|
|
3009
|
+
w = widthOf(usedHeight);
|
|
2927
3010
|
else if (box.replaced === 'hr')
|
|
2928
3011
|
w = room();
|
|
2929
3012
|
else
|
|
@@ -2932,7 +3015,7 @@ stretchRoom = containingWidth) {
|
|
|
2932
3015
|
if (usedHeight !== null)
|
|
2933
3016
|
h = usedHeight;
|
|
2934
3017
|
else if (ratio > 0)
|
|
2935
|
-
h = clamp(w
|
|
3018
|
+
h = clamp(heightOf(w), minH, maxH);
|
|
2936
3019
|
else
|
|
2937
3020
|
h = clamp(own.height, minH, maxH);
|
|
2938
3021
|
}
|
|
@@ -3213,9 +3296,15 @@ function layoutPositioned(box, containing, ctx) {
|
|
|
3213
3296
|
let y;
|
|
3214
3297
|
if (top !== null && bottom !== null) {
|
|
3215
3298
|
const fill = Math.max(0, cbHeight - top - bottom - box.marginTop - box.marginBottom);
|
|
3216
|
-
// — a box with a ratio has its height from its width
|
|
3299
|
+
// — a box with a ratio has its height from its width, and a table is
|
|
3300
|
+
// as tall as its rows, as it is as wide as its columns between two
|
|
3301
|
+
// offsets: `normal` stretches neither (Blink: "Replaced/tables don't
|
|
3302
|
+
// stretch in abspos", `out_of_flow_layout_part.cc`), and a table taken
|
|
3303
|
+
// to the height its offsets leave was that tall around rows that were
|
|
3304
|
+
// not
|
|
3217
3305
|
const stretches = style.height === AUTO &&
|
|
3218
3306
|
(box.kind !== 'replaced' || control) &&
|
|
3307
|
+
box.kind !== 'table' &&
|
|
3219
3308
|
!boxRatio(box);
|
|
3220
3309
|
// both offsets and no height: the box fills what they leave, its
|
|
3221
3310
|
// `auto` margins nothing (10.6.4, rule 5) — unless `min-height` or
|