@react-x11/components 0.12.0 → 0.14.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/html/controls.d.ts +41 -5
- package/dist/html/controls.d.ts.map +1 -1
- package/dist/html/controls.js +85 -57
- package/dist/html/controls.js.map +1 -1
- package/dist/html/css/cascade.d.ts +134 -20
- package/dist/html/css/cascade.d.ts.map +1 -1
- package/dist/html/css/cascade.js +545 -126
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/color.d.ts +18 -0
- package/dist/html/css/color.d.ts.map +1 -1
- package/dist/html/css/color.js +27 -0
- package/dist/html/css/color.js.map +1 -1
- package/dist/html/css/parse.d.ts +47 -6
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +336 -30
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/style.d.ts +142 -15
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +563 -147
- package/dist/html/css/style.js.map +1 -1
- package/dist/html/css/transform.d.ts +85 -0
- package/dist/html/css/transform.d.ts.map +1 -0
- package/dist/html/css/transform.js +425 -0
- package/dist/html/css/transform.js.map +1 -0
- package/dist/html/css/ua.d.ts +11 -1
- package/dist/html/css/ua.d.ts.map +1 -1
- package/dist/html/css/ua.js +73 -9
- package/dist/html/css/ua.js.map +1 -1
- package/dist/html/css/values.d.ts +4 -0
- package/dist/html/css/values.d.ts.map +1 -1
- package/dist/html/css/values.js.map +1 -1
- package/dist/html/dom.d.ts.map +1 -1
- package/dist/html/dom.js +3 -1
- package/dist/html/dom.js.map +1 -1
- package/dist/html/fonts.d.ts +78 -4
- package/dist/html/fonts.d.ts.map +1 -1
- package/dist/html/fonts.js +373 -19
- package/dist/html/fonts.js.map +1 -1
- package/dist/html/form.d.ts +200 -0
- package/dist/html/form.d.ts.map +1 -0
- package/dist/html/form.js +801 -0
- package/dist/html/form.js.map +1 -0
- package/dist/html/index.d.ts +12 -0
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +30 -301
- package/dist/html/index.js.map +1 -1
- package/dist/html/layout/axes.d.ts +14 -0
- package/dist/html/layout/axes.d.ts.map +1 -0
- package/dist/html/layout/axes.js +28 -0
- package/dist/html/layout/axes.js.map +1 -0
- package/dist/html/layout/block.d.ts +93 -12
- package/dist/html/layout/block.d.ts.map +1 -1
- package/dist/html/layout/block.js +393 -39
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +90 -2
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +74 -10
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/cache.d.ts +1 -1
- package/dist/html/layout/cache.d.ts.map +1 -1
- package/dist/html/layout/cache.js +6 -0
- package/dist/html/layout/cache.js.map +1 -1
- package/dist/html/layout/css-grid.d.ts.map +1 -1
- package/dist/html/layout/css-grid.js +90 -18
- 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 +574 -84
- package/dist/html/layout/flex.js.map +1 -1
- package/dist/html/layout/inline.d.ts +3 -0
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +154 -54
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/layout/multicol.d.ts +42 -0
- package/dist/html/layout/multicol.d.ts.map +1 -0
- package/dist/html/layout/multicol.js +897 -0
- package/dist/html/layout/multicol.js.map +1 -0
- package/dist/html/layout/shaping.d.ts +7 -0
- package/dist/html/layout/shaping.d.ts.map +1 -1
- package/dist/html/layout/shaping.js +25 -20
- package/dist/html/layout/shaping.js.map +1 -1
- package/dist/html/layout/table.d.ts.map +1 -1
- package/dist/html/layout/table.js +62 -18
- package/dist/html/layout/table.js.map +1 -1
- package/dist/html/node.d.ts +90 -15
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +771 -186
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts +101 -5
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +1502 -160
- package/dist/html/paint.js.map +1 -1
- package/dist/html/svg.d.ts +15 -2
- package/dist/html/svg.d.ts.map +1 -1
- package/dist/html/svg.js +249 -17
- package/dist/html/svg.js.map +1 -1
- package/dist/html/widgets.d.ts +29 -0
- package/dist/html/widgets.d.ts.map +1 -0
- package/dist/html/widgets.js +700 -0
- package/dist/html/widgets.js.map +1 -0
- package/dist/html/woff2.d.ts +14 -0
- package/dist/html/woff2.d.ts.map +1 -0
- package/dist/html/woff2.js +608 -0
- package/dist/html/woff2.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/maps/controller.d.ts +17 -1
- package/dist/maps/controller.d.ts.map +1 -1
- package/dist/maps/controller.js +27 -7
- package/dist/maps/controller.js.map +1 -1
- package/dist/richtext/node.d.ts +8 -1
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js +5 -1
- package/dist/richtext/node.js.map +1 -1
- package/dist/richtext/runs.d.ts +25 -6
- package/dist/richtext/runs.d.ts.map +1 -1
- package/dist/richtext/runs.js +240 -24
- package/dist/richtext/runs.js.map +1 -1
- package/package.json +2 -2
- package/src/html/controls.ts +114 -51
- package/src/html/css/cascade.ts +614 -140
- package/src/html/css/color.ts +29 -0
- package/src/html/css/parse.ts +388 -33
- package/src/html/css/style.ts +688 -150
- package/src/html/css/transform.ts +459 -0
- package/src/html/css/ua.ts +77 -10
- package/src/html/css/values.ts +4 -0
- package/src/html/dom.ts +3 -1
- package/src/html/fonts.ts +417 -24
- package/src/html/form.ts +962 -0
- package/src/html/index.ts +49 -338
- package/src/html/layout/axes.ts +62 -0
- package/src/html/layout/block.ts +447 -37
- package/src/html/layout/boxes.ts +143 -14
- package/src/html/layout/cache.ts +6 -0
- package/src/html/layout/css-grid.ts +95 -22
- package/src/html/layout/flex.ts +675 -78
- package/src/html/layout/inline.ts +159 -55
- package/src/html/layout/multicol.ts +977 -0
- package/src/html/layout/shaping.ts +27 -18
- package/src/html/layout/table.ts +62 -19
- package/src/html/node.ts +798 -172
- package/src/html/paint.ts +1742 -241
- package/src/html/svg.ts +277 -19
- package/src/html/widgets.ts +821 -0
- package/src/html/woff2.ts +612 -0
- package/src/index.ts +1 -0
- package/src/maps/controller.ts +28 -7
- package/src/richtext/node.ts +13 -2
- package/src/richtext/runs.ts +313 -35
|
@@ -42,8 +42,10 @@ import {
|
|
|
42
42
|
scrolls,
|
|
43
43
|
} from '../css/style.js';
|
|
44
44
|
import { inkColor, isTransparent, resolve } from '../css/values.js';
|
|
45
|
+
import { tagOf } from '../dom.js';
|
|
45
46
|
import {
|
|
46
47
|
BOX_RAISES,
|
|
48
|
+
GRID_TRACKS,
|
|
47
49
|
LINE_BOX_RAISES,
|
|
48
50
|
PADDED_FACES,
|
|
49
51
|
isOffset,
|
|
@@ -415,13 +417,21 @@ interface Cut {
|
|
|
415
417
|
function cutOf(
|
|
416
418
|
style: ComputedStyle,
|
|
417
419
|
clamp: InlineOptions['clamp'],
|
|
420
|
+
width: number,
|
|
418
421
|
): Cut | null {
|
|
419
422
|
// the ellipsis a clamp ends in is placed apart (`ellipsized`)
|
|
420
423
|
if (clamp) return { maxLines: clamp.lines, overflow: 'clip' };
|
|
424
|
+
// `text-overflow` is how the line is drawn where it runs out of its
|
|
425
|
+
// box, and no part of how wide it is (CSS Overflow 3, 5.1): in a box of
|
|
426
|
+
// no width, which shows none of it and is what the box's content is
|
|
427
|
+
// measured in at its least (`MIN_CONTENT_PROBE`), the line is left
|
|
428
|
+
// whole. Cut there, ntk left the ellipsis alone, and a button whose
|
|
429
|
+
// label is a `truncate` span was measured as wide as one
|
|
421
430
|
if (
|
|
422
431
|
style.textOverflow === 'ellipsis' &&
|
|
423
432
|
!wraps(style) &&
|
|
424
|
-
style.overflowX !== 'visible'
|
|
433
|
+
style.overflowX !== 'visible' &&
|
|
434
|
+
width > 0
|
|
425
435
|
) {
|
|
426
436
|
return { maxLines: 1, overflow: 'ellipsis', wrap: false };
|
|
427
437
|
}
|
|
@@ -644,7 +654,7 @@ function linesOf(
|
|
|
644
654
|
// line at a time, or the lines after the first were lost. A clamp is
|
|
645
655
|
// the paragraph's, and stays one layout.
|
|
646
656
|
const clamp = options.clamp;
|
|
647
|
-
let cut = cutOf(style, clamp);
|
|
657
|
+
let cut = cutOf(style, clamp, options.width);
|
|
648
658
|
const perLine = cut !== null && !clamp && hasNewline;
|
|
649
659
|
// an embedding cannot be cut into chunks
|
|
650
660
|
if (perLine && !hasControls(items)) {
|
|
@@ -920,6 +930,16 @@ function linesOf(
|
|
|
920
930
|
placeDeferred();
|
|
921
931
|
return;
|
|
922
932
|
}
|
|
933
|
+
// A line with no text on it — a control, an image or an inline-block
|
|
934
|
+
// that wrapped on its own — stands where the text around it does: an
|
|
935
|
+
// empty range at the end of the line before, not at 0. What finds a
|
|
936
|
+
// line by its text binary-searches these ranges as sorted
|
|
937
|
+
// (`lineBands`, `caretAt`), and a textless line at 0 after a line of
|
|
938
|
+
// text sent the search past every line: a `<label>` on the line
|
|
939
|
+
// before a submit button that wrapped measured as no box at all.
|
|
940
|
+
if (!line.texts.length && lines.length) {
|
|
941
|
+
line.textStart = line.textEnd = lines[lines.length - 1].textEnd;
|
|
942
|
+
}
|
|
923
943
|
lines.push(line);
|
|
924
944
|
widest = Math.max(widest, line.width);
|
|
925
945
|
y += line.height;
|
|
@@ -1410,6 +1430,7 @@ function linesOf(
|
|
|
1410
1430
|
if (!text) continue;
|
|
1411
1431
|
const m = hung.exec(text);
|
|
1412
1432
|
if (!m) break;
|
|
1433
|
+
if (!trailing) placed.trailRun = segment.runs[i];
|
|
1413
1434
|
trailing = m[0] + trailing;
|
|
1414
1435
|
if (m[0].length < text.length) break;
|
|
1415
1436
|
}
|
|
@@ -1426,6 +1447,7 @@ function linesOf(
|
|
|
1426
1447
|
: spaceAdvance(fonts, segment.runs[segment.runs.length - 1]) *
|
|
1427
1448
|
trailing.length;
|
|
1428
1449
|
open.x += open.hang;
|
|
1450
|
+
placed.trail = open.hang;
|
|
1429
1451
|
}
|
|
1430
1452
|
} else if (hung.total) holdHung();
|
|
1431
1453
|
index = segment.nextIndex;
|
|
@@ -2380,6 +2402,24 @@ function finishLine(
|
|
|
2380
2402
|
if (!open.texts.length && !open.atomics.length && !open.edges.length) {
|
|
2381
2403
|
return null;
|
|
2382
2404
|
}
|
|
2405
|
+
if (open.hang > 0) {
|
|
2406
|
+
// The line ends on the spaces its last text ends on, and they are
|
|
2407
|
+
// removed (CSS Text 3, 4.1.2): the text takes no room for them, and
|
|
2408
|
+
// what was set after them, the end edges of the boxes they are in,
|
|
2409
|
+
// stands where the text's content ends. Left a space past it, a list
|
|
2410
|
+
// item that ended its line was a space wider than its link.
|
|
2411
|
+
for (let i = open.order.length - 1; i >= 0; i -= 1) {
|
|
2412
|
+
const placed = open.order[i];
|
|
2413
|
+
if (placed.kind === 'text') {
|
|
2414
|
+
placed.item.trail = 0;
|
|
2415
|
+
placed.item.trailRun = undefined;
|
|
2416
|
+
break;
|
|
2417
|
+
}
|
|
2418
|
+
if (placed.kind !== 'edge') break;
|
|
2419
|
+
placed.at -= open.hang;
|
|
2420
|
+
placed.item.x -= open.hang;
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2383
2423
|
const reordered = levels
|
|
2384
2424
|
? levelPieces(open, levels) ||
|
|
2385
2425
|
open.order.some((p) => p.kind === 'edge' && needsOrdering(p, rtl))
|
|
@@ -3288,7 +3328,19 @@ function atomicRaise(
|
|
|
3288
3328
|
* be after.
|
|
3289
3329
|
*/
|
|
3290
3330
|
function atomicBaseline(box: Box): number {
|
|
3291
|
-
const
|
|
3331
|
+
const margin = box.height + box.marginTop + box.marginBottom;
|
|
3332
|
+
const button = isButton(box);
|
|
3333
|
+
// A `<button>` with no line in it sits on the bottom of its content box,
|
|
3334
|
+
// not of its margin box: where its label would have sat. No specification
|
|
3335
|
+
// says so and every browser does — Blink gives the element the content
|
|
3336
|
+
// box as the edge its baseline is synthesized from
|
|
3337
|
+
// (`HTMLButtonElement::AdjustStyle`). An icon button drawn of blocks, the
|
|
3338
|
+
// three bars of a menu toggle, stood its padding under the baseline, and
|
|
3339
|
+
// the line it was on was as much taller: GitHub's header, by four pixels.
|
|
3340
|
+
// And so one whose layout containment keeps its label's baseline in.
|
|
3341
|
+
const bottom = button
|
|
3342
|
+
? margin - box.marginBottom - box.borderBottom - box.padBottom
|
|
3343
|
+
: margin;
|
|
3292
3344
|
if (
|
|
3293
3345
|
box.kind === 'replaced' ||
|
|
3294
3346
|
// a box that clips sits on its bottom margin edge, for legacy reasons
|
|
@@ -3297,8 +3349,8 @@ function atomicBaseline(box: Box): number {
|
|
|
3297
3349
|
// sits on its first item's, as it does unclipped. A MediaWiki button
|
|
3298
3350
|
// is an `overflow: hidden` inline flex box of one icon, and stood its
|
|
3299
3351
|
// whole height on the baseline, the line under it the strut's descent
|
|
3300
|
-
// taller
|
|
3301
|
-
(scrolls(box.style) && box.kind !== 'flex') ||
|
|
3352
|
+
// taller. Nor a `<button>`, which sits on its label clipped or not
|
|
3353
|
+
(scrolls(box.style) && box.kind !== 'flex' && !button) ||
|
|
3302
3354
|
// layout containment keeps its baseline in (CSS Containment 2, 3.3)
|
|
3303
3355
|
box.style.contain & CONTAIN_LAYOUT
|
|
3304
3356
|
) {
|
|
@@ -3315,17 +3367,31 @@ function atomicBaseline(box: Box): number {
|
|
|
3315
3367
|
return baseline === null ? bottom : box.marginTop + (baseline - box.y);
|
|
3316
3368
|
}
|
|
3317
3369
|
|
|
3370
|
+
/** Whether a box is a `<button>` element's: one drawn as the document's,
|
|
3371
|
+
* which a replaced control is not. */
|
|
3372
|
+
export function isButton(box: Box): boolean {
|
|
3373
|
+
return (
|
|
3374
|
+
box.el !== null && box.kind !== 'replaced' && tagOf(box.el) === 'button'
|
|
3375
|
+
);
|
|
3376
|
+
}
|
|
3377
|
+
|
|
3318
3378
|
/**
|
|
3319
|
-
* A flex container's
|
|
3320
|
-
*
|
|
3321
|
-
*
|
|
3322
|
-
*
|
|
3323
|
-
*
|
|
3324
|
-
*
|
|
3325
|
-
*
|
|
3379
|
+
* A flex container's baseline, its first (CSS Flexbox 8.5): that of the
|
|
3380
|
+
* first item on its first line that is aligned by its baseline, or where
|
|
3381
|
+
* none is, of its first item, in `order`. An item gives its own, or where
|
|
3382
|
+
* it has none, its border box's bottom edge. Not its last child's: an
|
|
3383
|
+
* `inline-flex` of a small item and a big one sat on the big one's
|
|
3384
|
+
* baseline. Null for a box with no item.
|
|
3385
|
+
*
|
|
3386
|
+
* A grid's is that of its first item in row-major order, by where it was
|
|
3387
|
+
* placed and not where it was written (CSS Grid 1, 10.6).
|
|
3326
3388
|
*/
|
|
3327
|
-
function flexBaseline(box: Box
|
|
3328
|
-
|
|
3389
|
+
function flexBaseline(box: Box): number | null {
|
|
3390
|
+
if (box.style.grid) {
|
|
3391
|
+
const item = GRID_TRACKS.get(box)?.first;
|
|
3392
|
+
return item ? itemBaselineOf(item) : null;
|
|
3393
|
+
}
|
|
3394
|
+
const items: Box[] = [];
|
|
3329
3395
|
let reordered = false;
|
|
3330
3396
|
for (const child of box.children) {
|
|
3331
3397
|
if (child.outOfFlow || child.isFloat) continue;
|
|
@@ -3335,15 +3401,11 @@ function flexBaseline(box: Box, first: boolean): number | null {
|
|
|
3335
3401
|
}
|
|
3336
3402
|
if (!items.length) return null;
|
|
3337
3403
|
if (reordered) items.sort((a, b) => a.style.order - b.style.order);
|
|
3338
|
-
if (!first) items = items.reverse();
|
|
3339
3404
|
const style = box.style;
|
|
3340
|
-
if (style.flexDirection.startsWith('row')
|
|
3341
|
-
// a line ends where the next item does not go on along the main axis
|
|
3342
|
-
// which from the last item is where it goes on
|
|
3405
|
+
if (style.flexDirection.startsWith('row')) {
|
|
3406
|
+
// a line ends where the next item does not go on along the main axis
|
|
3343
3407
|
const back =
|
|
3344
|
-
(
|
|
3345
|
-
(style.direction === 'rtl')) !==
|
|
3346
|
-
!first;
|
|
3408
|
+
(style.flexDirection === 'row-reverse') !== (style.direction === 'rtl');
|
|
3347
3409
|
let last = NaN;
|
|
3348
3410
|
for (const item of items) {
|
|
3349
3411
|
if (!Number.isNaN(last) && (back ? item.x >= last : item.x <= last)) {
|
|
@@ -3354,24 +3416,20 @@ function flexBaseline(box: Box, first: boolean): number | null {
|
|
|
3354
3416
|
item.style.alignSelf === 'auto'
|
|
3355
3417
|
? style.alignItems
|
|
3356
3418
|
: item.style.alignSelf;
|
|
3357
|
-
if (align === 'baseline') return itemBaselineOf(item
|
|
3419
|
+
if (align === 'baseline') return itemBaselineOf(item);
|
|
3358
3420
|
}
|
|
3359
3421
|
}
|
|
3360
|
-
return itemBaselineOf(items[0]
|
|
3422
|
+
return itemBaselineOf(items[0]);
|
|
3361
3423
|
}
|
|
3362
3424
|
|
|
3363
|
-
/** A flex item's baseline, in document coordinates: its
|
|
3364
|
-
*
|
|
3365
|
-
*
|
|
3366
|
-
*
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
): number | null {
|
|
3372
|
-
const found = childBaseline(item, first ? firstBaselineIn : lastBaselineIn);
|
|
3373
|
-
if (found !== null) return found;
|
|
3374
|
-
return container.grid ? null : item.y + item.height;
|
|
3425
|
+
/** A flex item's baseline or a grid item's, in document coordinates: its
|
|
3426
|
+
* first line's, or where it has none, one synthesized from its border
|
|
3427
|
+
* edges, the bottom one (CSS Flexbox 8.5, CSS Grid 1, 10.6). A grid took
|
|
3428
|
+
* none from such an item and had none of its own: a grid of icons stood
|
|
3429
|
+
* its whole height on the baseline, where a browser stands it on the
|
|
3430
|
+
* first icon's bottom edge. */
|
|
3431
|
+
function itemBaselineOf(item: Box): number {
|
|
3432
|
+
return childBaseline(item, firstBaselineIn) ?? item.y + item.height;
|
|
3375
3433
|
}
|
|
3376
3434
|
|
|
3377
3435
|
/**
|
|
@@ -3399,10 +3457,18 @@ function tableBaseline(table: Box): number | null {
|
|
|
3399
3457
|
* what overflows it gives its bottom margin edge and no deeper, whatever
|
|
3400
3458
|
* text it holds (CSS Box Alignment's synthesized baseline). Null where
|
|
3401
3459
|
* nothing in it has one.
|
|
3460
|
+
*
|
|
3461
|
+
* A flex box or a grid among them gives its first baseline, the one it has
|
|
3462
|
+
* on a line of its own, and a table gives none: what an inline-block takes
|
|
3463
|
+
* from a block-level child in Blink, where only a block container is asked
|
|
3464
|
+
* for its last (`UseLastBaselineForInlineBaseline`), and in Gecko, where a
|
|
3465
|
+
* child is asked for its default one and a table is passed over
|
|
3466
|
+
* (`nsBlockFrame::GetNaturalBaselineBOffset`). Asked for its last, a grid
|
|
3467
|
+
* of an icon, a label and a chevron in a button sat the button on the
|
|
3468
|
+
* chevron, and the line it was on came out shorter than a browser's.
|
|
3402
3469
|
*/
|
|
3403
3470
|
function lastBaselineIn(box: Box): number | null {
|
|
3404
|
-
|
|
3405
|
-
if (box.kind === 'flex') return flexBaseline(box, false);
|
|
3471
|
+
if (box.kind === 'flex') return flexBaseline(box);
|
|
3406
3472
|
if (box.lines?.length) {
|
|
3407
3473
|
const line = box.lines[box.lines.length - 1];
|
|
3408
3474
|
return line.y + line.baseline;
|
|
@@ -3417,7 +3483,7 @@ function lastBaselineIn(box: Box): number | null {
|
|
|
3417
3483
|
/** The same, from the first line box or child: a table's baseline is its
|
|
3418
3484
|
* first row's, and so is a table cell's. */
|
|
3419
3485
|
export function firstBaselineIn(box: Box): number | null {
|
|
3420
|
-
if (box.kind === 'flex') return flexBaseline(box
|
|
3486
|
+
if (box.kind === 'flex') return flexBaseline(box);
|
|
3421
3487
|
if (box.lines?.length) return box.lines[0].y + box.lines[0].baseline;
|
|
3422
3488
|
for (const child of box.children) {
|
|
3423
3489
|
const found = childBaseline(child, firstBaselineIn);
|
|
@@ -3433,12 +3499,17 @@ function childBaseline(
|
|
|
3433
3499
|
if (child.outOfFlow || child.isFloat || child.kind === 'replaced') {
|
|
3434
3500
|
return null;
|
|
3435
3501
|
}
|
|
3502
|
+
// a table is passed over for a block's last baseline (`lastBaselineIn`)
|
|
3503
|
+
if (inside === lastBaselineIn && child.kind === 'table') return null;
|
|
3436
3504
|
// the legacy rule is a block container's last baseline alone (CSS Box
|
|
3437
|
-
// Alignment 3, 9.2): its first is its first line's, clipped or not
|
|
3505
|
+
// Alignment 3, 9.2): its first is its first line's, clipped or not —
|
|
3506
|
+
// and a button that clips keeps its label's, here as on a line of its
|
|
3507
|
+
// own (`atomicBaseline`)
|
|
3438
3508
|
if (
|
|
3439
3509
|
inside === lastBaselineIn &&
|
|
3440
3510
|
child.kind !== 'flex' &&
|
|
3441
|
-
scrolls(child.style)
|
|
3511
|
+
scrolls(child.style) &&
|
|
3512
|
+
!isButton(child)
|
|
3442
3513
|
) {
|
|
3443
3514
|
return child.y + child.height + child.marginBottom;
|
|
3444
3515
|
}
|
|
@@ -4133,6 +4204,8 @@ const RUN_STYLE = [
|
|
|
4133
4204
|
'underlineOffset',
|
|
4134
4205
|
'underlineThickness',
|
|
4135
4206
|
'strike',
|
|
4207
|
+
'strikeStyle',
|
|
4208
|
+
'strikeThickness',
|
|
4136
4209
|
] as const;
|
|
4137
4210
|
|
|
4138
4211
|
/**
|
|
@@ -4700,26 +4773,57 @@ export function runFor(text: string, style: ComputedStyle): TextRun {
|
|
|
4700
4773
|
// colours of the elements that set them (`decorate`)
|
|
4701
4774
|
if (style.underline) {
|
|
4702
4775
|
run.underline = style.underline;
|
|
4703
|
-
|
|
4704
|
-
//
|
|
4705
|
-
// `
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4776
|
+
run.underlineStyle = ruleStyle(style.underlineStyle);
|
|
4777
|
+
// The band the rule is drawn in: as thick as the box that set it made
|
|
4778
|
+
// it (`usedThickness`), and as far under the baseline as that box said.
|
|
4779
|
+
// `auto` leaves how far to the user agent, at or under the baseline
|
|
4780
|
+
// (CSS Text Decoration 4, 2.7 and 2.8), and it is half the rule's
|
|
4781
|
+
// thickness, a pixel at the least — Blink's gap, which keeps a thick
|
|
4782
|
+
// rule as clear of its letters as a thin one. A length is from the
|
|
4783
|
+
// baseline itself.
|
|
4784
|
+
const band = style.underlineThickness ?? 1;
|
|
4785
|
+
const top =
|
|
4786
|
+
style.underlineOffset === null
|
|
4787
|
+
? Math.max(1, Math.ceil(band / 2))
|
|
4788
|
+
: Math.round(style.underlineOffset);
|
|
4789
|
+
if (run.underlineStyle === 'dotted' || run.underlineStyle === 'dashed') {
|
|
4790
|
+
// dots and dashes are a stroke along the band's middle, its width the
|
|
4791
|
+
// nearest whole pixel to the band's: 1.6 is two, where a solid rule's
|
|
4792
|
+
// is the one pixel it fills
|
|
4793
|
+
const width = Math.round(band);
|
|
4794
|
+
run.underlineThickness = width;
|
|
4795
|
+
run.underlineOffset =
|
|
4796
|
+
top + Math.floor(Math.max(band / 2, 0.5)) - Math.floor(width / 2);
|
|
4797
|
+
} else {
|
|
4798
|
+
run.underlineThickness = Math.floor(band);
|
|
4799
|
+
run.underlineOffset = top;
|
|
4717
4800
|
}
|
|
4718
4801
|
}
|
|
4719
|
-
if (style.lineThrough)
|
|
4802
|
+
if (style.lineThrough) {
|
|
4803
|
+
run.strike = style.lineThrough;
|
|
4804
|
+
run.strikeStyle = ruleStyle(style.lineThroughStyle);
|
|
4805
|
+
// as thick as the box that set it made it, on whole pixels as the
|
|
4806
|
+
// underline's is: a solid rule fills the ones it covers, and dots and
|
|
4807
|
+
// dashes are the nearest whole pixel wide. Where it is drawn is each
|
|
4808
|
+
// run's own face's to say (`paintRunRules`).
|
|
4809
|
+
const band = style.lineThroughThickness ?? 1;
|
|
4810
|
+
run.strikeThickness =
|
|
4811
|
+
run.strikeStyle === 'dotted' || run.strikeStyle === 'dashed'
|
|
4812
|
+
? Math.round(band)
|
|
4813
|
+
: Math.floor(band);
|
|
4814
|
+
}
|
|
4720
4815
|
return run;
|
|
4721
4816
|
}
|
|
4722
4817
|
|
|
4818
|
+
/** A CSS rule style as richtext names it. CSS's five and SGR 4's five are
|
|
4819
|
+
* the same set under two names; richtext speaks SGR's, so `solid` is
|
|
4820
|
+
* `single` and `wavy` is `curly`. The other three are spelled identically. */
|
|
4821
|
+
function ruleStyle(
|
|
4822
|
+
style: ComputedStyle['underlineStyle'],
|
|
4823
|
+
): NonNullable<TextRun['underlineStyle']> {
|
|
4824
|
+
return style === 'wavy' ? 'curly' : style === 'solid' ? 'single' : style;
|
|
4825
|
+
}
|
|
4826
|
+
|
|
4723
4827
|
/**
|
|
4724
4828
|
* Maps a code-unit offset in text handed to `TextLayout` back to its offset
|
|
4725
4829
|
* in the document index. The two differ because a layout covers one segment
|