@react-x11/components 0.11.0 → 0.13.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/flow/node.d.ts +14 -6
- package/dist/flow/node.d.ts.map +1 -1
- package/dist/flow/node.js +82 -64
- package/dist/flow/node.js.map +1 -1
- package/dist/html/controls.d.ts +38 -10
- package/dist/html/controls.d.ts.map +1 -1
- package/dist/html/controls.js +43 -58
- 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 +538 -128
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/color.d.ts +19 -0
- package/dist/html/css/color.d.ts.map +1 -1
- package/dist/html/css/color.js +86 -0
- package/dist/html/css/color.js.map +1 -1
- package/dist/html/css/parse.d.ts +40 -2
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +391 -13
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/style.d.ts +52 -1
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +328 -11
- package/dist/html/css/style.js.map +1 -1
- 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 -7
- package/dist/html/css/ua.js.map +1 -1
- package/dist/html/css/values.d.ts +10 -1
- package/dist/html/css/values.d.ts.map +1 -1
- package/dist/html/css/values.js +27 -2
- package/dist/html/css/values.js.map +1 -1
- package/dist/html/css/vars.d.ts +5 -0
- package/dist/html/css/vars.d.ts.map +1 -1
- package/dist/html/css/vars.js +2 -2
- package/dist/html/css/vars.js.map +1 -1
- package/dist/html/dom.d.ts.map +1 -1
- package/dist/html/dom.js +38 -3
- package/dist/html/dom.js.map +1 -1
- package/dist/html/fonts.d.ts +25 -1
- package/dist/html/fonts.d.ts.map +1 -1
- package/dist/html/fonts.js +99 -6
- 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 -264
- package/dist/html/index.js.map +1 -1
- package/dist/html/layout/block.d.ts +11 -2
- package/dist/html/layout/block.d.ts.map +1 -1
- package/dist/html/layout/block.js +186 -19
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +65 -7
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +87 -22
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/cache.d.ts +2 -2
- package/dist/html/layout/cache.d.ts.map +1 -1
- package/dist/html/layout/cache.js +8 -3
- package/dist/html/layout/cache.js.map +1 -1
- package/dist/html/layout/flex.js +4 -1
- package/dist/html/layout/flex.js.map +1 -1
- package/dist/html/layout/floats.d.ts +4 -0
- package/dist/html/layout/floats.d.ts.map +1 -1
- package/dist/html/layout/floats.js +26 -0
- package/dist/html/layout/floats.js.map +1 -1
- package/dist/html/layout/inline.d.ts +26 -2
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +1232 -115
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/node.d.ts +120 -15
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +993 -174
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts +75 -2
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +836 -200
- package/dist/html/paint.js.map +1 -1
- package/dist/html/surfaces.d.ts +7 -2
- package/dist/html/surfaces.d.ts.map +1 -1
- package/dist/html/surfaces.js +16 -0
- package/dist/html/surfaces.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 +620 -0
- package/dist/html/widgets.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/internal/window.d.ts +22 -0
- package/dist/internal/window.d.ts.map +1 -1
- package/dist/internal/window.js +35 -8
- package/dist/internal/window.js.map +1 -1
- package/dist/richtext/node.d.ts +7 -0
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js.map +1 -1
- package/package.json +6 -4
- package/src/flow/node.ts +80 -64
- package/src/html/controls.ts +79 -58
- package/src/html/css/cascade.ts +610 -146
- package/src/html/css/color.ts +87 -0
- package/src/html/css/parse.ts +431 -13
- package/src/html/css/style.ts +367 -11
- package/src/html/css/ua.ts +76 -8
- package/src/html/css/values.ts +31 -3
- package/src/html/css/vars.ts +2 -2
- package/src/html/dom.ts +41 -3
- package/src/html/fonts.ts +116 -6
- package/src/html/form.ts +962 -0
- package/src/html/index.ts +49 -300
- package/src/html/layout/block.ts +231 -16
- package/src/html/layout/boxes.ts +133 -32
- package/src/html/layout/cache.ts +8 -3
- package/src/html/layout/flex.ts +4 -1
- package/src/html/layout/floats.ts +24 -0
- package/src/html/layout/inline.ts +1445 -108
- package/src/html/node.ts +1010 -166
- package/src/html/paint.ts +980 -270
- package/src/html/surfaces.ts +21 -1
- package/src/html/widgets.ts +735 -0
- package/src/index.ts +1 -0
- package/src/internal/window.ts +36 -8
- package/src/richtext/node.ts +7 -0
package/src/html/layout/boxes.ts
CHANGED
|
@@ -28,7 +28,12 @@ import {
|
|
|
28
28
|
NON_RENDERED,
|
|
29
29
|
tagOf,
|
|
30
30
|
} from '../dom.js';
|
|
31
|
-
import type {
|
|
31
|
+
import type {
|
|
32
|
+
Cascade,
|
|
33
|
+
FirstLetterRules,
|
|
34
|
+
KeptStyles,
|
|
35
|
+
SelectionStyle,
|
|
36
|
+
} from '../css/cascade.js';
|
|
32
37
|
import type { CollapsedTable } from './collapse.js';
|
|
33
38
|
import { quoteAt } from '../css/content.js';
|
|
34
39
|
import type { CounterStyles } from '../css/counter-styles.js';
|
|
@@ -36,6 +41,7 @@ import type { ContentItem } from '../css/content.js';
|
|
|
36
41
|
import {
|
|
37
42
|
CONTAIN_STYLE,
|
|
38
43
|
FIRST_LINE_INHERITED,
|
|
44
|
+
NO_MASK,
|
|
39
45
|
copyStyle,
|
|
40
46
|
firstLineParent,
|
|
41
47
|
inherit,
|
|
@@ -187,6 +193,15 @@ export interface LineText {
|
|
|
187
193
|
* spacer: a unit of the layout that is no text of the document's
|
|
188
194
|
* (`documentOffsetOf`, `layoutOffsetOf`). */
|
|
189
195
|
gaps?: number[];
|
|
196
|
+
/**
|
|
197
|
+
* The spaces `pre-wrap` keeps that this fragment's line ends on, which an
|
|
198
|
+
* engine strips from a line's end as though CSS removed them there: each
|
|
199
|
+
* one's offset in the layout's text and where it is, from the layout's
|
|
200
|
+
* origin, beside the line's end in logical order (`hangPreserved`). They
|
|
201
|
+
* are their inline box's, whose background and border cover them, and
|
|
202
|
+
* the ones before a forced break that fit take room on the line.
|
|
203
|
+
*/
|
|
204
|
+
hung?: { at: number; x: number; width: number }[];
|
|
190
205
|
/** Any offset in the layout's own text as a document index — how a run
|
|
191
206
|
* under the pointer finds the element whose text it is. Per pass: the
|
|
192
207
|
* layout may be one an earlier pass made (`TextLayoutCache`), and the
|
|
@@ -233,6 +248,10 @@ export interface TextLayoutLike {
|
|
|
233
248
|
height: number;
|
|
234
249
|
baseline: number;
|
|
235
250
|
width: number;
|
|
251
|
+
/** Its width with the white space it ends on kept, in the item it
|
|
252
|
+
* ends: how far it moves the pen where text goes on after it on the
|
|
253
|
+
* same line. ntk's, from 8.17.0; an engine without it leaves it out. */
|
|
254
|
+
advance?: number;
|
|
236
255
|
ascent: number;
|
|
237
256
|
descent: number;
|
|
238
257
|
start: number;
|
|
@@ -542,6 +561,10 @@ export type FirstLineStyler = (
|
|
|
542
561
|
parent: ComputedStyle,
|
|
543
562
|
) => ComputedStyle;
|
|
544
563
|
|
|
564
|
+
/** The `::selection` of the element a box's text is in, or null for the
|
|
565
|
+
* palette's highlight (`Cascade.selectionStyle`). */
|
|
566
|
+
export type SelectionStyler = (box: Box | null) => SelectionStyle | null;
|
|
567
|
+
|
|
545
568
|
/** The url of an image generated content put in a pseudo-element: it has
|
|
546
569
|
* no element of its own to name it (`imageUrlOf`). */
|
|
547
570
|
export const CONTENT_IMAGES = new WeakMap<Box, string>();
|
|
@@ -581,6 +604,12 @@ export const BOX_RAISES = new WeakMap<Box, number>();
|
|
|
581
604
|
* background, drawn from its baseline, is put there by line. */
|
|
582
605
|
export const LINE_BOX_RAISES = new WeakMap<LineBox, Map<Box, number>>();
|
|
583
606
|
|
|
607
|
+
/** The face of an inline box with padding above or below its text and
|
|
608
|
+
* nothing to paint behind it, which has no `decoration`: its fragments
|
|
609
|
+
* still reach past its lines by the padding, and count in the scrollable
|
|
610
|
+
* overflow of the block they are in (`computePaintBounds`). */
|
|
611
|
+
export const PADDED_FACES = new WeakMap<Box, InlineDecoration>();
|
|
612
|
+
|
|
584
613
|
/** The table cells wholly in columns `visibility: collapse` took out of
|
|
585
614
|
* their table (CSS 2.1 17.5.5), which the paint pass leaves out: a cell is
|
|
586
615
|
* no descendant of its column and inherits nothing from it, so its own
|
|
@@ -615,11 +644,23 @@ export const GRID_TRACKS = new WeakMap<Box, GridTracks>();
|
|
|
615
644
|
* `order` moves any: an absolutely positioned child's is 0. */
|
|
616
645
|
export const PAINT_ORDER = new WeakMap<Box, Box[]>();
|
|
617
646
|
|
|
618
|
-
/** The blocks that broke
|
|
619
|
-
*
|
|
620
|
-
* though they stand outside it
|
|
647
|
+
/** The blocks that broke an inline box in pieces, under its first piece
|
|
648
|
+
* (`breakAround`): a relative offset of the box moves them too (CSS 2.1
|
|
649
|
+
* 9.2.1.1), though they stand outside it, and its rect takes them in, as
|
|
650
|
+
* a browser's does (`elementRect`). */
|
|
621
651
|
export const CUT_BLOCKS = new WeakMap<Box, Box[]>();
|
|
622
652
|
|
|
653
|
+
/** Where a block that clearance moved below the floats would have stood
|
|
654
|
+
* without it, its border edge's top (CSS 2.1 9.5.2): a browser's
|
|
655
|
+
* fragment of an inline box around such a block starts there, and takes
|
|
656
|
+
* the clearance in (`elementRect`). Only the blocks that had clearance. */
|
|
657
|
+
export const CLEARED_FROM = new WeakMap<Box, number>();
|
|
658
|
+
|
|
659
|
+
/** The element a pseudo-element's box is generated from, which has no
|
|
660
|
+
* element of its own (`Box.pseudo`): whose the images its styles name are,
|
|
661
|
+
* when the host is asked for them. */
|
|
662
|
+
export const GENERATED_FROM = new WeakMap<Box, Element>();
|
|
663
|
+
|
|
623
664
|
/** The blocks that broke an inline box under full opacity in pieces, and
|
|
624
665
|
* the opacity they take from it — from each such inline box around them,
|
|
625
666
|
* multiplied. They stand outside it (CSS 2.1 9.2.1.1) and are still its
|
|
@@ -647,9 +688,14 @@ export interface BoxTree {
|
|
|
647
688
|
controls: Box[];
|
|
648
689
|
/** Every box carrying an `href`, for click and hover. */
|
|
649
690
|
links: Box[];
|
|
650
|
-
/**
|
|
651
|
-
*
|
|
652
|
-
*
|
|
691
|
+
/** The style of an anonymous box under a parent's (`anonymousStyles`):
|
|
692
|
+
* the one the fix-up gave each it made, and what such a box takes when
|
|
693
|
+
* its parent's style changes where it is (`HtmlViewNode._hoverInPlace`). */
|
|
694
|
+
anonymous: AnonymousStyle;
|
|
695
|
+
/** Every box with a `background-image`, a border image or a mask image,
|
|
696
|
+
* an element's or a pseudo-element's, for the host to be asked for: a
|
|
697
|
+
* document has a handful, and finding them was a walk over every box
|
|
698
|
+
* after every build. */
|
|
653
699
|
backgrounds: Box[];
|
|
654
700
|
/** Every image generated content names, the element whose
|
|
655
701
|
* pseudo-element names it, for the host to be asked for, and whether its
|
|
@@ -667,6 +713,10 @@ export interface BoxTree {
|
|
|
667
713
|
/** Each box's style on a first line (`FirstLineStyler`), where any
|
|
668
714
|
* block has a `::first-line`. */
|
|
669
715
|
firstLineStyler: FirstLineStyler | null;
|
|
716
|
+
/** Each box's `::selection` (`SelectionStyler`), where any rule styles
|
|
717
|
+
* one: worked out as a selection is first painted over it, not as the
|
|
718
|
+
* tree is built, since most builds are never selected in. */
|
|
719
|
+
selectionStyler: SelectionStyler | null;
|
|
670
720
|
/** Whether a float or an out-of-flow box sits in an inline box: where
|
|
671
721
|
* none does, layout looks for them among a block's own children and
|
|
672
722
|
* goes through no inline box to find them. */
|
|
@@ -687,6 +737,9 @@ export interface BoxTree {
|
|
|
687
737
|
|
|
688
738
|
export interface BuildOptions {
|
|
689
739
|
cascade: Cascade;
|
|
740
|
+
/** The styles of the tree this one replaces, where only some elements'
|
|
741
|
+
* can have changed since (`Cascade.beginSharing`). */
|
|
742
|
+
kept?: KeptStyles | null;
|
|
690
743
|
/** Device pixels per CSS pixel. An image's pixels and a `width="600"`
|
|
691
744
|
* attribute are CSS pixels; every box is device, so both are multiplied
|
|
692
745
|
* on the way in. Default 1. */
|
|
@@ -786,7 +839,7 @@ class Builder {
|
|
|
786
839
|
|
|
787
840
|
run(root: Element): BoxTree {
|
|
788
841
|
const cascade = this._options.cascade;
|
|
789
|
-
cascade.beginSharing();
|
|
842
|
+
cascade.beginSharing(this._options.kept ?? null);
|
|
790
843
|
const { style: rootStyle, html: impliedHtml } = cascade.rootStyle(
|
|
791
844
|
hasBody(root),
|
|
792
845
|
hasHtml(root),
|
|
@@ -805,10 +858,13 @@ class Builder {
|
|
|
805
858
|
// it carries no margins of its own and cannot collapse with anything.
|
|
806
859
|
this._children(root, rootBox, rootStyle, false, null, ROOT_SHARE_KEY);
|
|
807
860
|
this._endLine();
|
|
808
|
-
|
|
861
|
+
cascade.endSharing();
|
|
862
|
+
const anonymous = anonymousStyles(cascade.initial);
|
|
863
|
+
fixUp(rootBox, anonymous);
|
|
809
864
|
assignSubtreeRanges(rootBox);
|
|
810
865
|
return {
|
|
811
866
|
root: rootBox,
|
|
867
|
+
anonymous,
|
|
812
868
|
text: this._chunks.join(''),
|
|
813
869
|
textBoxes: this._textBoxes,
|
|
814
870
|
textStyles: this._textStyles,
|
|
@@ -821,6 +877,7 @@ class Builder {
|
|
|
821
877
|
negative: this._negative,
|
|
822
878
|
firstLine: this._firstLine,
|
|
823
879
|
firstLineStyler: this._firstLine ? this._firstLineStyler() : null,
|
|
880
|
+
selectionStyler: cascade.hasSelection ? this._selectionStyler() : null,
|
|
824
881
|
nestedOutOfLine: this._nestedOutOfLine,
|
|
825
882
|
movedInline: this._movedInline,
|
|
826
883
|
clipText: this._clipText,
|
|
@@ -828,6 +885,30 @@ class Builder {
|
|
|
828
885
|
};
|
|
829
886
|
}
|
|
830
887
|
|
|
888
|
+
/** `BoxTree.selectionStyler`, over this build's cascade: an element's
|
|
889
|
+
* over its parent's, each once. A box with no element of its own — text,
|
|
890
|
+
* an anonymous box — is its nearest element's. */
|
|
891
|
+
private _selectionStyler(): SelectionStyler {
|
|
892
|
+
const cascade = this._options.cascade;
|
|
893
|
+
const styles = this._styles;
|
|
894
|
+
const known = new Map<Element, SelectionStyle | null>();
|
|
895
|
+
const of = (el: Element): SelectionStyle | null => {
|
|
896
|
+
let found = known.get(el);
|
|
897
|
+
if (found !== undefined) return found;
|
|
898
|
+
// the parser keeps a document to 256 elements deep (`dom.ts`)
|
|
899
|
+
const parent = isElement(el.parent) ? of(el.parent) : null;
|
|
900
|
+
const own = styles.get(el)?.style;
|
|
901
|
+
found = own ? cascade.selectionStyle(el, own, parent) : parent;
|
|
902
|
+
known.set(el, found);
|
|
903
|
+
return found;
|
|
904
|
+
};
|
|
905
|
+
return (box) => {
|
|
906
|
+
let at = box;
|
|
907
|
+
while (at && !at.el) at = at.parent;
|
|
908
|
+
return at?.el ? of(at.el) : null;
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
|
|
831
912
|
/** `BoxTree.firstLineStyler`, over this build's cascade. */
|
|
832
913
|
private _firstLineStyler(): FirstLineStyler {
|
|
833
914
|
const cascade = this._options.cascade;
|
|
@@ -997,7 +1078,9 @@ class Builder {
|
|
|
997
1078
|
}
|
|
998
1079
|
|
|
999
1080
|
// an `<object>` is its image once it has one, and its content until;
|
|
1000
|
-
// an `<embed>` its image, and a `<video>` its poster, or a frame
|
|
1081
|
+
// an `<embed>` its image, and a `<video>` its poster, or a frame; an
|
|
1082
|
+
// image button its image, and a button saying what it is for until it
|
|
1083
|
+
// has one, so it can be pressed either way
|
|
1001
1084
|
const replaced =
|
|
1002
1085
|
tag === 'object'
|
|
1003
1086
|
? this._options.imageSize(el)
|
|
@@ -1005,7 +1088,11 @@ class Builder {
|
|
|
1005
1088
|
: 'none'
|
|
1006
1089
|
: (tag === 'embed' || tag === 'video') && this._options.imageSize(el)
|
|
1007
1090
|
? 'image'
|
|
1008
|
-
:
|
|
1091
|
+
: isImageButton(el, tag)
|
|
1092
|
+
? this._options.imageSize(el)
|
|
1093
|
+
? 'image'
|
|
1094
|
+
: 'button'
|
|
1095
|
+
: replacedKind(el, tag);
|
|
1009
1096
|
if (replaced !== 'none') {
|
|
1010
1097
|
this._replaced(el, tag, replaced, style, into);
|
|
1011
1098
|
return;
|
|
@@ -1025,13 +1112,7 @@ class Builder {
|
|
|
1025
1112
|
this._firstLine = true;
|
|
1026
1113
|
}
|
|
1027
1114
|
}
|
|
1028
|
-
if (
|
|
1029
|
-
style.backgroundImage ||
|
|
1030
|
-
style.backgroundImages ||
|
|
1031
|
-
typeof style.borderImage.source === 'string'
|
|
1032
|
-
) {
|
|
1033
|
-
this._backgrounds.push(box);
|
|
1034
|
-
}
|
|
1115
|
+
if (namesImages(style)) this._backgrounds.push(box);
|
|
1035
1116
|
if (style.position === 'absolute' || style.position === 'fixed')
|
|
1036
1117
|
box.outOfFlow = true;
|
|
1037
1118
|
else if (style.float !== 'none') box.isFloat = true;
|
|
@@ -1158,13 +1239,7 @@ class Builder {
|
|
|
1158
1239
|
const box = new Box('replaced', el, style);
|
|
1159
1240
|
box.replaced = replaced;
|
|
1160
1241
|
into.append(box);
|
|
1161
|
-
if (
|
|
1162
|
-
style.backgroundImage ||
|
|
1163
|
-
style.backgroundImages ||
|
|
1164
|
-
typeof style.borderImage.source === 'string'
|
|
1165
|
-
) {
|
|
1166
|
-
this._backgrounds.push(box);
|
|
1167
|
-
}
|
|
1242
|
+
if (namesImages(style)) this._backgrounds.push(box);
|
|
1168
1243
|
if (style.position === 'absolute' || style.position === 'fixed')
|
|
1169
1244
|
box.outOfFlow = true;
|
|
1170
1245
|
else if (style.float !== 'none') box.isFloat = true;
|
|
@@ -1295,6 +1370,10 @@ class Builder {
|
|
|
1295
1370
|
const box = new Box(boxKindFor(style.display), null, style);
|
|
1296
1371
|
box.pseudo = which;
|
|
1297
1372
|
into.append(box);
|
|
1373
|
+
// its images are its element's to ask for: a `::after` with no content
|
|
1374
|
+
// but a background, which designs hang a picture on, drew nothing
|
|
1375
|
+
GENERATED_FROM.set(box, el);
|
|
1376
|
+
if (namesImages(style)) this._backgrounds.push(box);
|
|
1298
1377
|
// a list item it generates has a marker as an element's has, of the
|
|
1299
1378
|
// `list-item` counter it has just counted (CSS 2.1 12.5): outside it,
|
|
1300
1379
|
// or at the start of its content
|
|
@@ -1714,6 +1793,10 @@ class Builder {
|
|
|
1714
1793
|
const letterStyle = cascade.firstLetterStyle(search.rules, style);
|
|
1715
1794
|
const box = new Box(boxKindFor(letterStyle.display), null, letterStyle);
|
|
1716
1795
|
box.pseudo = 'first-letter';
|
|
1796
|
+
if (owner) {
|
|
1797
|
+
GENERATED_FROM.set(box, owner);
|
|
1798
|
+
if (namesImages(letterStyle)) this._backgrounds.push(box);
|
|
1799
|
+
}
|
|
1717
1800
|
if (letterStyle.float !== 'none') {
|
|
1718
1801
|
box.isFloat = true;
|
|
1719
1802
|
if (into.kind === 'inline') this._nestedOutOfLine = true;
|
|
@@ -2336,6 +2419,13 @@ function setIntrinsics(box: Box, size: IntrinsicSize, scale: number): void {
|
|
|
2336
2419
|
};
|
|
2337
2420
|
}
|
|
2338
2421
|
|
|
2422
|
+
/** An `<input type=image>`: a picture that submits its form. */
|
|
2423
|
+
function isImageButton(el: Element, tag: string): boolean {
|
|
2424
|
+
return (
|
|
2425
|
+
tag === 'input' && (attr(el, 'type') ?? '').trim().toLowerCase() === 'image'
|
|
2426
|
+
);
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2339
2429
|
function replacedKind(el: Element, tag: string): ReplacedKind {
|
|
2340
2430
|
switch (tag) {
|
|
2341
2431
|
case 'img':
|
|
@@ -2608,7 +2698,7 @@ function breakAround(inline: Box): Box[] | null {
|
|
|
2608
2698
|
for (let i = 0; i < pieces.length; i += 1) {
|
|
2609
2699
|
pieces[i].cut = (i > 0 ? 1 : 0) | (i < pieces.length - 1 ? 2 : 0);
|
|
2610
2700
|
}
|
|
2611
|
-
|
|
2701
|
+
CUT_BLOCKS.set(pieces[0], blocks);
|
|
2612
2702
|
const fade = inline.style.opacity;
|
|
2613
2703
|
if (fade < 1) {
|
|
2614
2704
|
for (const block of blocks) {
|
|
@@ -2618,6 +2708,17 @@ function breakAround(inline: Box): Box[] | null {
|
|
|
2618
2708
|
return out;
|
|
2619
2709
|
}
|
|
2620
2710
|
|
|
2711
|
+
/** Whether a style names an image for its box to be drawn with: a
|
|
2712
|
+
* background's, a border's, or a mask's. */
|
|
2713
|
+
function namesImages(style: ComputedStyle): boolean {
|
|
2714
|
+
return (
|
|
2715
|
+
!!style.backgroundImage ||
|
|
2716
|
+
!!style.backgroundImages ||
|
|
2717
|
+
typeof style.borderImage.source === 'string' ||
|
|
2718
|
+
style.mask !== NO_MASK
|
|
2719
|
+
);
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2621
2722
|
/**
|
|
2622
2723
|
* The style of an anonymous box inside a parent: what the parent passes on
|
|
2623
2724
|
* by inheritance, and every other property at its initial value, as CSS 2.1
|
|
@@ -2628,24 +2729,24 @@ function breakAround(inline: Box): Box[] | null {
|
|
|
2628
2729
|
* paragraph after it the height of the div further down. One per parent
|
|
2629
2730
|
* style, which the cascade already shares between elements.
|
|
2630
2731
|
*/
|
|
2631
|
-
type AnonymousStyle = (
|
|
2632
|
-
parent:
|
|
2732
|
+
export type AnonymousStyle = (
|
|
2733
|
+
parent: ComputedStyle,
|
|
2633
2734
|
display: ComputedStyle['display'],
|
|
2634
2735
|
) => ComputedStyle;
|
|
2635
2736
|
|
|
2636
2737
|
function anonymousStyles(initial: ComputedStyle): AnonymousStyle {
|
|
2637
2738
|
const made = new WeakMap<ComputedStyle, Map<string, ComputedStyle>>();
|
|
2638
2739
|
return (parent, display) => {
|
|
2639
|
-
let byDisplay = made.get(parent
|
|
2740
|
+
let byDisplay = made.get(parent);
|
|
2640
2741
|
if (!byDisplay) {
|
|
2641
2742
|
byDisplay = new Map();
|
|
2642
|
-
made.set(parent
|
|
2743
|
+
made.set(parent, byDisplay);
|
|
2643
2744
|
}
|
|
2644
2745
|
let style = byDisplay.get(display);
|
|
2645
2746
|
if (!style) {
|
|
2646
2747
|
// `display` is the one property it does not start from: it is the
|
|
2647
2748
|
// box the fix-up made, and layout asks the style what a box is
|
|
2648
|
-
style = inherit(parent
|
|
2749
|
+
style = inherit(parent, initial);
|
|
2649
2750
|
style.display = display;
|
|
2650
2751
|
byDisplay.set(display, style);
|
|
2651
2752
|
}
|
|
@@ -2753,7 +2854,7 @@ function anonymousOf(
|
|
|
2753
2854
|
anonymous: AnonymousStyle,
|
|
2754
2855
|
display: ComputedStyle['display'] = kind as ComputedStyle['display'],
|
|
2755
2856
|
): Box {
|
|
2756
|
-
const box = new Box(kind, null, anonymous(parent, display));
|
|
2857
|
+
const box = new Box(kind, null, anonymous(parent.style, display));
|
|
2757
2858
|
box.parent = parent;
|
|
2758
2859
|
for (const child of run) {
|
|
2759
2860
|
child.parent = box;
|
package/src/html/layout/cache.ts
CHANGED
|
@@ -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
|
}
|
package/src/html/layout/flex.ts
CHANGED
|
@@ -478,7 +478,10 @@ function placeItems(
|
|
|
478
478
|
definite,
|
|
479
479
|
!row,
|
|
480
480
|
);
|
|
481
|
-
|
|
481
|
+
// to the end of its margin box, as Yoga measured the box: a negative
|
|
482
|
+
// margin takes the item's end back in, which Codex's search field
|
|
483
|
+
// hangs a pixel over its form's border with, top and bottom
|
|
484
|
+
bottom = Math.max(bottom, top + child.height + child.marginBottom);
|
|
482
485
|
}
|
|
483
486
|
return bottom;
|
|
484
487
|
}
|
|
@@ -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 {
|