@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.
- package/dist/code/index.d.ts.map +1 -1
- package/dist/code/index.js +25 -24
- package/dist/code/index.js.map +1 -1
- package/dist/code-language/index.d.ts +1 -1
- package/dist/code-language/index.d.ts.map +1 -1
- package/dist/code-language/index.js +1 -1
- package/dist/code-language/index.js.map +1 -1
- package/dist/code-language/runs.d.ts +31 -0
- package/dist/code-language/runs.d.ts.map +1 -1
- package/dist/code-language/runs.js +105 -0
- package/dist/code-language/runs.js.map +1 -1
- package/dist/codeblock/index.d.ts +13 -0
- package/dist/codeblock/index.d.ts.map +1 -1
- package/dist/codeblock/index.js +37 -1
- package/dist/codeblock/index.js.map +1 -1
- 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 +26 -7
- package/dist/html/controls.d.ts.map +1 -1
- package/dist/html/controls.js +28 -3
- package/dist/html/controls.js.map +1 -1
- package/dist/html/css/cascade.d.ts +32 -10
- package/dist/html/css/cascade.d.ts.map +1 -1
- package/dist/html/css/cascade.js +89 -31
- 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 +11 -0
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +114 -4
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/style.d.ts +45 -5
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +363 -14
- package/dist/html/css/style.js.map +1 -1
- package/dist/html/css/ua.js +22 -5
- 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 +35 -2
- package/dist/html/dom.js.map +1 -1
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +38 -1
- 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 +306 -25
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +61 -6
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +65 -16
- 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/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 +29 -2
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +1454 -125
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/node.d.ts +33 -0
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +608 -86
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts +53 -1
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +746 -214
- 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/svg.d.ts.map +1 -1
- package/dist/html/svg.js +27 -20
- package/dist/html/svg.js.map +1 -1
- package/dist/internal/codelines.d.ts +42 -0
- package/dist/internal/codelines.d.ts.map +1 -0
- package/dist/internal/codelines.js +170 -0
- package/dist/internal/codelines.js.map +1 -0
- 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/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +98 -26
- package/dist/markdown/index.js.map +1 -1
- package/dist/rich-text-editor/index.d.ts.map +1 -1
- package/dist/rich-text-editor/index.js +3 -8
- package/dist/rich-text-editor/index.js.map +1 -1
- package/dist/rich-text-editor/markdown.d.ts.map +1 -1
- package/dist/rich-text-editor/markdown.js +30 -1
- package/dist/rich-text-editor/markdown.js.map +1 -1
- package/dist/rich-text-editor/replace.d.ts +13 -0
- package/dist/rich-text-editor/replace.d.ts.map +1 -0
- package/dist/rich-text-editor/replace.js +64 -0
- package/dist/rich-text-editor/replace.js.map +1 -0
- 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/dist/terminal-output/index.d.ts.map +1 -1
- package/dist/terminal-output/index.js +100 -25
- package/dist/terminal-output/index.js.map +1 -1
- package/dist/terminal-output/runs.d.ts +4 -1
- package/dist/terminal-output/runs.d.ts.map +1 -1
- package/dist/terminal-output/runs.js +5 -1
- package/dist/terminal-output/runs.js.map +1 -1
- package/package.json +5 -3
- package/src/code/index.ts +34 -32
- package/src/code-language/index.ts +1 -1
- package/src/code-language/runs.ts +111 -1
- package/src/codeblock/index.ts +48 -1
- package/src/flow/node.ts +80 -64
- package/src/html/controls.ts +50 -9
- package/src/html/css/cascade.ts +134 -43
- package/src/html/css/color.ts +87 -0
- package/src/html/css/parse.ts +107 -4
- package/src/html/css/style.ts +386 -23
- package/src/html/css/ua.ts +22 -5
- package/src/html/css/values.ts +31 -3
- package/src/html/css/vars.ts +2 -2
- package/src/html/dom.ts +38 -2
- package/src/html/index.ts +39 -1
- package/src/html/layout/block.ts +360 -22
- package/src/html/layout/boxes.ts +98 -23
- package/src/html/layout/cache.ts +8 -3
- package/src/html/layout/floats.ts +24 -0
- package/src/html/layout/inline.ts +1690 -119
- package/src/html/node.ts +648 -101
- package/src/html/paint.ts +883 -283
- package/src/html/surfaces.ts +21 -1
- package/src/html/svg.ts +30 -19
- package/src/internal/codelines.ts +200 -0
- package/src/internal/window.ts +36 -8
- package/src/markdown/index.ts +145 -26
- package/src/rich-text-editor/index.ts +3 -11
- package/src/rich-text-editor/markdown.ts +36 -1
- package/src/rich-text-editor/replace.ts +85 -0
- package/src/richtext/node.ts +7 -0
- package/src/terminal-output/index.ts +127 -34
- package/src/terminal-output/runs.ts +16 -2
package/src/html/css/style.ts
CHANGED
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
} from './content.js';
|
|
41
41
|
import type { ContentItem, CounterChange } from './content.js';
|
|
42
42
|
import type { CustomProps } from './vars.js';
|
|
43
|
+
import { LIGHT_DARK, lightDark, usedColorScheme } from './color.js';
|
|
43
44
|
|
|
44
45
|
export type Display =
|
|
45
46
|
| 'none'
|
|
@@ -202,6 +203,14 @@ export type ContentSize =
|
|
|
202
203
|
export interface ComputedStyle {
|
|
203
204
|
// --- inherited ------------------------------------------------------------
|
|
204
205
|
color: string;
|
|
206
|
+
/**
|
|
207
|
+
* The colour scheme the element is drawn in (CSS Color Adjust 1, 2.2):
|
|
208
|
+
* its `color-scheme` resolved against the scheme the palette is, which
|
|
209
|
+
* stands for the reader's preference, as it does for `@media
|
|
210
|
+
* (prefers-color-scheme)`. What a `light-dark()` picks by. `normal` is
|
|
211
|
+
* the palette's own, since the palette is this renderer's default look.
|
|
212
|
+
*/
|
|
213
|
+
colorScheme: 'light' | 'dark';
|
|
205
214
|
fontFamily: string;
|
|
206
215
|
fontSize: number;
|
|
207
216
|
fontWeight: number;
|
|
@@ -320,6 +329,11 @@ export interface ComputedStyle {
|
|
|
320
329
|
float: 'none' | 'left' | 'right';
|
|
321
330
|
clear: 'none' | 'left' | 'right' | 'both';
|
|
322
331
|
boxSizing: 'content-box' | 'border-box';
|
|
332
|
+
/** `box-decoration-break` (CSS Fragmentation 3, 5.4): how an inline box
|
|
333
|
+
* that goes on to another line places its background images and
|
|
334
|
+
* gradients — `slice`, from its fragments laid end to end as one box,
|
|
335
|
+
* or `clone`, from each fragment's own. */
|
|
336
|
+
boxDecorationBreak: 'slice' | 'clone';
|
|
323
337
|
/** Whether a block is a line-clamp container, and how many lines of its
|
|
324
338
|
* formatting context it shows (CSS Overflow 4, 5.3.1): its `max-lines`,
|
|
325
339
|
* or Infinity for `line-clamp: auto`, which shows as many as its height
|
|
@@ -497,14 +511,18 @@ export interface ComputedStyle {
|
|
|
497
511
|
/** `background-clip` and `background-origin` (CSS Backgrounds 3, 3.7 and
|
|
498
512
|
* 3.8): the box a layer is painted in and the box it is placed in, the
|
|
499
513
|
* colour painted in the bottom layer's; each a list as the four above. */
|
|
500
|
-
backgroundClip:
|
|
514
|
+
backgroundClip: BackgroundClip;
|
|
501
515
|
backgroundOrigin: VisualBox;
|
|
502
|
-
backgroundClips:
|
|
516
|
+
backgroundClips: BackgroundClip[] | null;
|
|
503
517
|
backgroundOrigins: VisualBox[] | null;
|
|
504
518
|
/** `border-image` and its longhands (CSS Backgrounds 3, 6): one object,
|
|
505
519
|
* replaced whole when any of them changes, and `NO_BORDER_IMAGE` where
|
|
506
520
|
* nothing sets them. */
|
|
507
521
|
borderImage: BorderImage;
|
|
522
|
+
/** `mask-image` and the longhands that place its layers (CSS Masking 1,
|
|
523
|
+
* 7): one object, replaced whole when any of them changes, and
|
|
524
|
+
* `NO_MASK` where nothing sets them. */
|
|
525
|
+
mask: MaskLayers;
|
|
508
526
|
/** `-webkit-text-fill-color`: what the glyphs are filled with where it
|
|
509
527
|
* is not the text's `color` — Tailwind's `text-transparent` over a
|
|
510
528
|
* `bg-clip-text` gradient; null for `color`, as `currentColor` is. */
|
|
@@ -608,6 +626,7 @@ export interface ComputedStyle {
|
|
|
608
626
|
* same list. */
|
|
609
627
|
export const INHERITED = [
|
|
610
628
|
'color',
|
|
629
|
+
'colorScheme',
|
|
611
630
|
'textFillColor',
|
|
612
631
|
'fontFamily',
|
|
613
632
|
'fontSize',
|
|
@@ -689,6 +708,7 @@ export function initialStyle(look: RootLook, scale = 1): ComputedStyle {
|
|
|
689
708
|
// a copy of the literal, not the literal: see `copyStyle`
|
|
690
709
|
return copyStyle({
|
|
691
710
|
color: look.color,
|
|
711
|
+
colorScheme: look.colorScheme,
|
|
692
712
|
fontFamily: look.fontFamily,
|
|
693
713
|
fontSize: look.fontSize,
|
|
694
714
|
fontWeight: 400,
|
|
@@ -747,6 +767,7 @@ export function initialStyle(look: RootLook, scale = 1): ComputedStyle {
|
|
|
747
767
|
float: 'none',
|
|
748
768
|
clear: 'none',
|
|
749
769
|
boxSizing: 'content-box',
|
|
770
|
+
boxDecorationBreak: 'slice',
|
|
750
771
|
lineClamp: null,
|
|
751
772
|
maxLines: null,
|
|
752
773
|
clampContinue: 'auto',
|
|
@@ -846,6 +867,7 @@ export function initialStyle(look: RootLook, scale = 1): ComputedStyle {
|
|
|
846
867
|
backgroundClips: null,
|
|
847
868
|
backgroundOrigins: null,
|
|
848
869
|
borderImage: NO_BORDER_IMAGE,
|
|
870
|
+
mask: NO_MASK,
|
|
849
871
|
textFillColor: null,
|
|
850
872
|
|
|
851
873
|
textDecorationLine: 'none',
|
|
@@ -941,6 +963,7 @@ export function inherit(
|
|
|
941
963
|
// quarters of the cost of every element's style, a store through a
|
|
942
964
|
// computed name costing thirty times one through a written one
|
|
943
965
|
out.color = parent.color;
|
|
966
|
+
out.colorScheme = parent.colorScheme;
|
|
944
967
|
out.textFillColor = parent.textFillColor;
|
|
945
968
|
out.fontFamily = parent.fontFamily;
|
|
946
969
|
out.fontSize = parent.fontSize;
|
|
@@ -1162,6 +1185,15 @@ export function applyDeclaration(
|
|
|
1162
1185
|
if (/!\s*important$/i.test(value)) {
|
|
1163
1186
|
value = value.replace(/!\s*important$/i, '').trim();
|
|
1164
1187
|
}
|
|
1188
|
+
// the branch of each `light-dark()` this element's scheme picks, before
|
|
1189
|
+
// anything reads the value: it stands wherever a colour can, in a
|
|
1190
|
+
// shorthand, a shadow, a gradient or a mix, and most often arrives
|
|
1191
|
+
// through a `var()` from a theme on `:root`
|
|
1192
|
+
if (LIGHT_DARK.test(value)) {
|
|
1193
|
+
const picked = lightDark(value, style.colorScheme);
|
|
1194
|
+
if (picked === null) return;
|
|
1195
|
+
value = picked;
|
|
1196
|
+
}
|
|
1165
1197
|
|
|
1166
1198
|
const color = COLOR_PROPS[name];
|
|
1167
1199
|
if (color) {
|
|
@@ -1178,6 +1210,12 @@ export function applyDeclaration(
|
|
|
1178
1210
|
}
|
|
1179
1211
|
|
|
1180
1212
|
switch (name) {
|
|
1213
|
+
case 'color-scheme': {
|
|
1214
|
+
const scheme = usedColorScheme(value, ctx.initial?.colorScheme);
|
|
1215
|
+
if (scheme) style.colorScheme = scheme;
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1181
1219
|
// --- box ----------------------------------------------------------------
|
|
1182
1220
|
case 'display': {
|
|
1183
1221
|
const v = value.toLowerCase();
|
|
@@ -1366,6 +1404,12 @@ export function applyDeclaration(
|
|
|
1366
1404
|
if (v === 'border-box' || v === 'content-box') style.boxSizing = v;
|
|
1367
1405
|
return;
|
|
1368
1406
|
}
|
|
1407
|
+
case 'box-decoration-break':
|
|
1408
|
+
case '-webkit-box-decoration-break': {
|
|
1409
|
+
const v = value.trim().toLowerCase();
|
|
1410
|
+
if (v === 'slice' || v === 'clone') style.boxDecorationBreak = v;
|
|
1411
|
+
return;
|
|
1412
|
+
}
|
|
1369
1413
|
case 'aspect-ratio': {
|
|
1370
1414
|
const parsed = parseAspectRatio(value);
|
|
1371
1415
|
if (parsed !== undefined) style.aspectRatio = parsed;
|
|
@@ -1799,14 +1843,29 @@ export function applyDeclaration(
|
|
|
1799
1843
|
}
|
|
1800
1844
|
case 'background-clip':
|
|
1801
1845
|
case '-webkit-background-clip': {
|
|
1802
|
-
// `text` the first layer's alone, which paints through the text
|
|
1846
|
+
// `text` the first layer's alone, which paints through the text —
|
|
1847
|
+
// and with `border-area` through its border as well, in either order
|
|
1848
|
+
// (CSS Backgrounds 4, 2.1)
|
|
1803
1849
|
const clips = layerValues(value, (part) => {
|
|
1804
1850
|
const v = part.toLowerCase();
|
|
1805
|
-
|
|
1851
|
+
if (v === 'text' || isBackgroundClip(v)) return v;
|
|
1852
|
+
const [a, b, more] = splitValue(v);
|
|
1853
|
+
return !more &&
|
|
1854
|
+
((a === 'border-area' && b === 'text') ||
|
|
1855
|
+
(a === 'text' && b === 'border-area'))
|
|
1856
|
+
? 'border-area text'
|
|
1857
|
+
: null;
|
|
1806
1858
|
});
|
|
1807
1859
|
if (!clips) return;
|
|
1808
|
-
style.backgroundClipText =
|
|
1809
|
-
|
|
1860
|
+
style.backgroundClipText =
|
|
1861
|
+
clips[0] === 'text' || clips[0] === 'border-area text';
|
|
1862
|
+
const boxes = clips.map((c): BackgroundClip =>
|
|
1863
|
+
c === 'text'
|
|
1864
|
+
? 'border-box'
|
|
1865
|
+
: c === 'border-area text'
|
|
1866
|
+
? 'border-area'
|
|
1867
|
+
: (c as BackgroundClip),
|
|
1868
|
+
);
|
|
1810
1869
|
style.backgroundClip = boxes[0];
|
|
1811
1870
|
style.backgroundClips = boxes.length > 1 ? boxes : null;
|
|
1812
1871
|
return;
|
|
@@ -1891,6 +1950,67 @@ export function applyDeclaration(
|
|
|
1891
1950
|
return;
|
|
1892
1951
|
}
|
|
1893
1952
|
|
|
1953
|
+
// --- masking --------------------------------------------------------------
|
|
1954
|
+
// Each `-webkit-` name is the same property's (Compatibility, 5): every
|
|
1955
|
+
// engine takes both, and a page writes both — Wikipedia's icons do.
|
|
1956
|
+
case 'mask':
|
|
1957
|
+
case '-webkit-mask': {
|
|
1958
|
+
const mask = readMask(value, ctx);
|
|
1959
|
+
if (mask) style.mask = mask;
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
case 'mask-image':
|
|
1963
|
+
case '-webkit-mask-image': {
|
|
1964
|
+
// `none` a layer as much as an image is; a bad url drops it all
|
|
1965
|
+
const images: BackgroundImage[] = [];
|
|
1966
|
+
for (const part of splitCommas(value)) {
|
|
1967
|
+
const image = maskImageOf(part, ctx);
|
|
1968
|
+
if (image === undefined) return;
|
|
1969
|
+
images.push(image);
|
|
1970
|
+
}
|
|
1971
|
+
if (images.length) style.mask = { ...style.mask, images };
|
|
1972
|
+
return;
|
|
1973
|
+
}
|
|
1974
|
+
case 'mask-repeat':
|
|
1975
|
+
case '-webkit-mask-repeat': {
|
|
1976
|
+
const repeats = layerValues(value, (part) => {
|
|
1977
|
+
const words = splitValue(part.toLowerCase());
|
|
1978
|
+
return words.length <= 2 ? readRepeat(words) : null;
|
|
1979
|
+
});
|
|
1980
|
+
if (repeats) style.mask = { ...style.mask, repeats };
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1983
|
+
case 'mask-size':
|
|
1984
|
+
case '-webkit-mask-size': {
|
|
1985
|
+
const sizes = layerValues(value, (part) =>
|
|
1986
|
+
backgroundSizeOf(splitValue(part), ctx),
|
|
1987
|
+
);
|
|
1988
|
+
if (sizes) style.mask = { ...style.mask, sizes };
|
|
1989
|
+
return;
|
|
1990
|
+
}
|
|
1991
|
+
case 'mask-position':
|
|
1992
|
+
case '-webkit-mask-position': {
|
|
1993
|
+
const positions = layerValues(value, (part) =>
|
|
1994
|
+
positionPair(splitValue(part), ctx),
|
|
1995
|
+
);
|
|
1996
|
+
if (positions) style.mask = { ...style.mask, positions };
|
|
1997
|
+
return;
|
|
1998
|
+
}
|
|
1999
|
+
case 'mask-origin':
|
|
2000
|
+
case '-webkit-mask-origin': {
|
|
2001
|
+
const origins = layerValues(value, (part) => maskBox(part));
|
|
2002
|
+
if (origins) style.mask = { ...style.mask, origins };
|
|
2003
|
+
return;
|
|
2004
|
+
}
|
|
2005
|
+
case 'mask-clip':
|
|
2006
|
+
case '-webkit-mask-clip': {
|
|
2007
|
+
const clips = layerValues(value, (part) =>
|
|
2008
|
+
part.toLowerCase() === 'no-clip' ? 'border-box' : maskBox(part),
|
|
2009
|
+
);
|
|
2010
|
+
if (clips) style.mask = { ...style.mask, clips };
|
|
2011
|
+
return;
|
|
2012
|
+
}
|
|
2013
|
+
|
|
1894
2014
|
// --- generated content --------------------------------------------------
|
|
1895
2015
|
case 'content': {
|
|
1896
2016
|
const parsed = parseContent(value);
|
|
@@ -1998,7 +2118,13 @@ export function applyDeclaration(
|
|
|
1998
2118
|
style.lineHeight = len;
|
|
1999
2119
|
style.lineHeightIsLength = true;
|
|
2000
2120
|
} else if (len && typeof len === 'object') {
|
|
2001
|
-
|
|
2121
|
+
// a percentage of the element's own font size, the one it is
|
|
2122
|
+
// computed with (CSS 2.1 10.8.1), which `em` already is: not the
|
|
2123
|
+
// size in `style` as this declaration comes up, which a `font`
|
|
2124
|
+
// earlier in the same rule has just set to its own — `p { font:
|
|
2125
|
+
// 12px …; line-height: 100% }` under a `.lead { font-size: 16px }`
|
|
2126
|
+
// set sixteen-pixel text on twelve-pixel lines
|
|
2127
|
+
const px = resolve(len, ctx.em);
|
|
2002
2128
|
if (px < 0) return;
|
|
2003
2129
|
style.lineHeight = px;
|
|
2004
2130
|
style.lineHeightIsLength = true;
|
|
@@ -2447,7 +2573,12 @@ export function applyDeclaration(
|
|
|
2447
2573
|
return;
|
|
2448
2574
|
}
|
|
2449
2575
|
case 'align-content': {
|
|
2450
|
-
|
|
2576
|
+
// `normal` is `stretch` in a flex and a grid container, the only
|
|
2577
|
+
// boxes it moves anything in (CSS Box Alignment 3, 5.1)
|
|
2578
|
+
const v =
|
|
2579
|
+
value.trim().toLowerCase() === 'normal'
|
|
2580
|
+
? 'stretch'
|
|
2581
|
+
: alignKeyword(value);
|
|
2451
2582
|
if (v) style.alignContent = v as ComputedStyle['alignContent'];
|
|
2452
2583
|
return;
|
|
2453
2584
|
}
|
|
@@ -2682,6 +2813,30 @@ export function applyDeclaration(
|
|
|
2682
2813
|
}
|
|
2683
2814
|
return;
|
|
2684
2815
|
}
|
|
2816
|
+
case 'place-content': {
|
|
2817
|
+
// `<'align-content'> <'justify-content'>?` (CSS Box Alignment 3,
|
|
2818
|
+
// 5.3), either half one keyword or two — `first baseline`, `safe
|
|
2819
|
+
// center` — and the second the first again where it is left out,
|
|
2820
|
+
// but for a baseline, which is no `justify-content`: `start`
|
|
2821
|
+
const words = value.trim().toLowerCase().split(/\s+/);
|
|
2822
|
+
const span = (at: number) =>
|
|
2823
|
+
/^(?:safe|unsafe|first|last)$/.test(words[at] ?? '') ? 2 : 1;
|
|
2824
|
+
const cut = span(0);
|
|
2825
|
+
const align = words.slice(0, cut).join(' ');
|
|
2826
|
+
const rest = words.slice(cut);
|
|
2827
|
+
if (rest.length && rest.length !== span(cut)) return;
|
|
2828
|
+
const justify = rest.length
|
|
2829
|
+
? rest.join(' ')
|
|
2830
|
+
: /baseline$/.test(align)
|
|
2831
|
+
? 'start'
|
|
2832
|
+
: align;
|
|
2833
|
+
// a shorthand is one declaration: either half unread drops both
|
|
2834
|
+
if (align !== 'normal' && !alignKeyword(align)) return;
|
|
2835
|
+
if (!justifyKeyword(justify)) return;
|
|
2836
|
+
applyDeclaration(style, parent, 'align-content', align, ctx);
|
|
2837
|
+
applyDeclaration(style, parent, 'justify-content', justify, ctx);
|
|
2838
|
+
return;
|
|
2839
|
+
}
|
|
2685
2840
|
case 'place-items':
|
|
2686
2841
|
case 'place-self': {
|
|
2687
2842
|
const parts = splitValue(value);
|
|
@@ -2877,12 +3032,6 @@ export function settleOverflow(style: ComputedStyle): void {
|
|
|
2877
3032
|
else style.overflowX = x === 'visible' ? 'auto' : 'hidden';
|
|
2878
3033
|
}
|
|
2879
3034
|
|
|
2880
|
-
/**
|
|
2881
|
-
* Whether a box is a scroll container: its `overflow` is neither `visible`
|
|
2882
|
-
* nor `clip`. `clip` cuts what overflows as `hidden` does, but makes no
|
|
2883
|
-
* formatting context and keeps a flex or grid item's automatic minimum
|
|
2884
|
-
* (CSS Overflow 3, 3.1) — so only this asks it apart from `hidden`.
|
|
2885
|
-
*/
|
|
2886
3035
|
/** A `<visual-box>` (CSS Box 4): the edge of a box a property names. */
|
|
2887
3036
|
export type VisualBox = 'border-box' | 'padding-box' | 'content-box';
|
|
2888
3037
|
|
|
@@ -2890,6 +3039,20 @@ function isVisualBox(v: string): v is VisualBox {
|
|
|
2890
3039
|
return v === 'border-box' || v === 'padding-box' || v === 'content-box';
|
|
2891
3040
|
}
|
|
2892
3041
|
|
|
3042
|
+
/** Where a background layer is painted: inside one of the box's edges, or
|
|
3043
|
+
* `border-area`, in what its border paints (CSS Backgrounds 4, 2.1). */
|
|
3044
|
+
export type BackgroundClip = VisualBox | 'border-area';
|
|
3045
|
+
|
|
3046
|
+
function isBackgroundClip(v: string): v is BackgroundClip {
|
|
3047
|
+
return v === 'border-area' || isVisualBox(v);
|
|
3048
|
+
}
|
|
3049
|
+
|
|
3050
|
+
/**
|
|
3051
|
+
* Whether a box is a scroll container: its `overflow` is neither `visible`
|
|
3052
|
+
* nor `clip`. `clip` cuts what overflows as `hidden` does, but makes no
|
|
3053
|
+
* formatting context and keeps a flex or grid item's automatic minimum
|
|
3054
|
+
* (CSS Overflow 3, 3.1) — so only this asks it apart from `hidden`.
|
|
3055
|
+
*/
|
|
2893
3056
|
export function scrolls(style: ComputedStyle): boolean {
|
|
2894
3057
|
const x = style.overflowX;
|
|
2895
3058
|
const y = style.overflowY;
|
|
@@ -3121,6 +3284,157 @@ export const NO_BORDER_IMAGE: BorderImage = {
|
|
|
3121
3284
|
repeat: ['stretch', 'stretch'],
|
|
3122
3285
|
};
|
|
3123
3286
|
|
|
3287
|
+
/**
|
|
3288
|
+
* An element's mask layers (CSS Masking 1, 7), top first, a list a
|
|
3289
|
+
* property as a background's are: each layer takes the images' place in
|
|
3290
|
+
* the others, and they repeat where they are fewer. A layer's image is a
|
|
3291
|
+
* url, a gradient, or null for `none` — which is the one layer of an
|
|
3292
|
+
* element that is not masked.
|
|
3293
|
+
*/
|
|
3294
|
+
export interface MaskLayers {
|
|
3295
|
+
images: readonly BackgroundImage[];
|
|
3296
|
+
repeats: readonly BackgroundRepeat[];
|
|
3297
|
+
sizes: readonly ComputedStyle['backgroundSize'][];
|
|
3298
|
+
positions: readonly (readonly [Len, Len])[];
|
|
3299
|
+
/** The box a layer is placed in, and the one it is painted in: the
|
|
3300
|
+
* border box unless a layer says (7.5, 7.6). */
|
|
3301
|
+
origins: readonly VisualBox[];
|
|
3302
|
+
clips: readonly VisualBox[];
|
|
3303
|
+
}
|
|
3304
|
+
|
|
3305
|
+
/** Whether a style masks its element: a layer of its mask has an image. */
|
|
3306
|
+
export function masked(style: ComputedStyle): boolean {
|
|
3307
|
+
const mask = style.mask;
|
|
3308
|
+
if (mask === NO_MASK) return false;
|
|
3309
|
+
for (const image of mask.images) if (image !== null) return true;
|
|
3310
|
+
return false;
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
/**
|
|
3314
|
+
* One layer's `mask-image`: a url, a gradient — or none, for an image
|
|
3315
|
+
* function this does not draw, or a `url(#id)`, which names an SVG
|
|
3316
|
+
* `<mask>` element in the document rather than an image to fetch (7.2):
|
|
3317
|
+
* drawn with no mask rather than as the transparent layer a mask that
|
|
3318
|
+
* cannot be had is, since this draws no `<mask>`. Undefined where it is no
|
|
3319
|
+
* image at all.
|
|
3320
|
+
*/
|
|
3321
|
+
function maskImageOf(
|
|
3322
|
+
text: string,
|
|
3323
|
+
ctx: UnitContext,
|
|
3324
|
+
): BackgroundImage | undefined {
|
|
3325
|
+
const image = backgroundImageOf(text, ctx);
|
|
3326
|
+
return typeof image === 'string' && image[0] === '#' ? null : image;
|
|
3327
|
+
}
|
|
3328
|
+
|
|
3329
|
+
/** A `<geometry-box>` as an HTML element has it (CSS Masking 1, 7.5): the
|
|
3330
|
+
* SVG boxes are its content box and its border box. */
|
|
3331
|
+
function maskBox(text: string): VisualBox | null {
|
|
3332
|
+
const v = text.trim().toLowerCase();
|
|
3333
|
+
if (isVisualBox(v)) return v;
|
|
3334
|
+
if (v === 'fill-box') return 'content-box';
|
|
3335
|
+
if (v === 'stroke-box' || v === 'view-box') return 'border-box';
|
|
3336
|
+
return null;
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3339
|
+
/**
|
|
3340
|
+
* The `mask` shorthand (CSS Masking 1, 7.10): a layer a comma group, each
|
|
3341
|
+
* an image, a position with a size after a `/`, a repeat, one box for the
|
|
3342
|
+
* origin and the clip or two, `no-clip`, a compositing operator and a
|
|
3343
|
+
* mode, each at most once, in any order. The operator and the mode are
|
|
3344
|
+
* read and not honoured: layers are added, and an image masks by its
|
|
3345
|
+
* alpha, which is what `match-source` makes of one. Null where a layer is
|
|
3346
|
+
* not one, which drops the declaration.
|
|
3347
|
+
*/
|
|
3348
|
+
function readMask(value: string, ctx: UnitContext): MaskLayers | null {
|
|
3349
|
+
const out = {
|
|
3350
|
+
images: [] as BackgroundImage[],
|
|
3351
|
+
repeats: [] as BackgroundRepeat[],
|
|
3352
|
+
sizes: [] as ComputedStyle['backgroundSize'][],
|
|
3353
|
+
positions: [] as [Len, Len][],
|
|
3354
|
+
origins: [] as VisualBox[],
|
|
3355
|
+
clips: [] as VisualBox[],
|
|
3356
|
+
};
|
|
3357
|
+
for (const text of splitCommas(value)) {
|
|
3358
|
+
const parts = splitValue(text).flatMap(splitSlash);
|
|
3359
|
+
let image: BackgroundImage = null;
|
|
3360
|
+
let repeat = NO_MASK.repeats[0];
|
|
3361
|
+
let size: ComputedStyle['backgroundSize'] = 'auto';
|
|
3362
|
+
let position: [Len, Len] = [0, 0];
|
|
3363
|
+
const boxes: VisualBox[] = [];
|
|
3364
|
+
let seen = 0;
|
|
3365
|
+
const once = (bit: number): boolean => {
|
|
3366
|
+
if (seen & bit) return false;
|
|
3367
|
+
seen |= bit;
|
|
3368
|
+
return true;
|
|
3369
|
+
};
|
|
3370
|
+
for (let i = 0; i < parts.length;) {
|
|
3371
|
+
const part = parts[i];
|
|
3372
|
+
const v = part.toLowerCase();
|
|
3373
|
+
if (v === 'none' || v.startsWith('url(') || IMAGE_FUNCTION.test(v)) {
|
|
3374
|
+
if (!once(1)) return null;
|
|
3375
|
+
const read = maskImageOf(part, ctx);
|
|
3376
|
+
if (read === undefined) return null;
|
|
3377
|
+
image = read;
|
|
3378
|
+
i += 1;
|
|
3379
|
+
} else if (v === 'repeat-x' || v === 'repeat-y' || REPEATS.has(v)) {
|
|
3380
|
+
if (!once(2)) return null;
|
|
3381
|
+
const pair = REPEATS.has(v) && REPEATS.has(parts[i + 1]?.toLowerCase());
|
|
3382
|
+
const read = readRepeat(pair ? [v, parts[i + 1].toLowerCase()] : [v]);
|
|
3383
|
+
if (!read) return null;
|
|
3384
|
+
repeat = read;
|
|
3385
|
+
i += pair ? 2 : 1;
|
|
3386
|
+
} else if (maskBox(v) || v === 'no-clip') {
|
|
3387
|
+
if (boxes.length === 2 || (v === 'no-clip' && !once(4))) return null;
|
|
3388
|
+
boxes.push(maskBox(v) ?? 'border-box');
|
|
3389
|
+
i += 1;
|
|
3390
|
+
} else if (/^(?:add|subtract|intersect|exclude)$/.test(v)) {
|
|
3391
|
+
if (!once(8)) return null;
|
|
3392
|
+
i += 1;
|
|
3393
|
+
} else if (/^(?:alpha|luminance|match-source)$/.test(v)) {
|
|
3394
|
+
if (!once(16)) return null;
|
|
3395
|
+
i += 1;
|
|
3396
|
+
} else if (isPositionPart(v, ctx)) {
|
|
3397
|
+
if (!once(32)) return null;
|
|
3398
|
+
let end = i;
|
|
3399
|
+
while (
|
|
3400
|
+
end < parts.length &&
|
|
3401
|
+
isPositionPart(parts[end].toLowerCase(), ctx)
|
|
3402
|
+
) {
|
|
3403
|
+
end += 1;
|
|
3404
|
+
}
|
|
3405
|
+
const read = positionPair(parts.slice(i, end), ctx);
|
|
3406
|
+
if (!read) return null;
|
|
3407
|
+
position = read;
|
|
3408
|
+
i = end;
|
|
3409
|
+
if (parts[i] !== '/') continue;
|
|
3410
|
+
const first = parts[i + 1]?.toLowerCase();
|
|
3411
|
+
if (first === 'cover' || first === 'contain') {
|
|
3412
|
+
size = first;
|
|
3413
|
+
i += 2;
|
|
3414
|
+
} else if (first !== undefined && isSizePart(first, ctx)) {
|
|
3415
|
+
const two =
|
|
3416
|
+
i + 2 < parts.length && isSizePart(parts[i + 2].toLowerCase(), ctx);
|
|
3417
|
+
size =
|
|
3418
|
+
backgroundSizeOf(parts.slice(i + 1, i + (two ? 3 : 2)), ctx) ??
|
|
3419
|
+
'auto';
|
|
3420
|
+
i += two ? 3 : 2;
|
|
3421
|
+
} else {
|
|
3422
|
+
return null;
|
|
3423
|
+
}
|
|
3424
|
+
} else {
|
|
3425
|
+
return null;
|
|
3426
|
+
}
|
|
3427
|
+
}
|
|
3428
|
+
out.images.push(image);
|
|
3429
|
+
out.repeats.push(repeat);
|
|
3430
|
+
out.sizes.push(size);
|
|
3431
|
+
out.positions.push(position);
|
|
3432
|
+
out.origins.push(boxes[0] ?? 'border-box');
|
|
3433
|
+
out.clips.push(boxes[1] ?? boxes[0] ?? 'border-box');
|
|
3434
|
+
}
|
|
3435
|
+
return out.images.length ? out : null;
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3124
3438
|
/** One to four values, one a side as `margin` takes them; null where one
|
|
3125
3439
|
* is not a value. */
|
|
3126
3440
|
function sidesOf<T>(
|
|
@@ -3315,6 +3629,15 @@ function repeatPair(x: RepeatMode, y: RepeatMode): BackgroundRepeat {
|
|
|
3315
3629
|
|
|
3316
3630
|
const REPEAT = repeatPair('repeat', 'repeat');
|
|
3317
3631
|
|
|
3632
|
+
export const NO_MASK: MaskLayers = {
|
|
3633
|
+
images: [null],
|
|
3634
|
+
repeats: [REPEAT],
|
|
3635
|
+
sizes: ['auto'],
|
|
3636
|
+
positions: [[0, 0]],
|
|
3637
|
+
origins: ['border-box'],
|
|
3638
|
+
clips: ['border-box'],
|
|
3639
|
+
};
|
|
3640
|
+
|
|
3318
3641
|
function applyBorderShorthand(
|
|
3319
3642
|
style: ComputedStyle,
|
|
3320
3643
|
name: string,
|
|
@@ -3485,7 +3808,7 @@ interface BackgroundLayer {
|
|
|
3485
3808
|
size: ComputedStyle['backgroundSize'];
|
|
3486
3809
|
attachment: ComputedStyle['backgroundAttachment'];
|
|
3487
3810
|
origin: VisualBox;
|
|
3488
|
-
clip:
|
|
3811
|
+
clip: BackgroundClip;
|
|
3489
3812
|
position: [Len, Len] | null;
|
|
3490
3813
|
}
|
|
3491
3814
|
|
|
@@ -3545,9 +3868,14 @@ function readBackgroundLayer(
|
|
|
3545
3868
|
layer.attachment = v;
|
|
3546
3869
|
i += 1;
|
|
3547
3870
|
} else if (isVisualBox(v)) {
|
|
3548
|
-
// one box is both the origin and the clip, and a second the clip
|
|
3549
|
-
|
|
3871
|
+
// one box is both the origin and the clip, and a second the clip —
|
|
3872
|
+
// which `border-area` is instead of, and the one box the origin
|
|
3873
|
+
if ((boxes += 1) > (seen & 32 ? 1 : 2)) return null;
|
|
3550
3874
|
if (boxes === 1) layer.origin = v;
|
|
3875
|
+
if (!(seen & 32)) layer.clip = v;
|
|
3876
|
+
i += 1;
|
|
3877
|
+
} else if (v === 'border-area') {
|
|
3878
|
+
if (boxes > 1 || !once(32)) return null;
|
|
3551
3879
|
layer.clip = v;
|
|
3552
3880
|
i += 1;
|
|
3553
3881
|
} else if (isPositionPart(v, ctx)) {
|
|
@@ -3998,12 +4326,10 @@ function applyFontShorthand(
|
|
|
3998
4326
|
style.lineHeight = 'normal';
|
|
3999
4327
|
style.lineHeightIsLength = false;
|
|
4000
4328
|
applyDeclaration(style, parent, 'font-size', sizeText, ctx);
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
});
|
|
4006
|
-
}
|
|
4329
|
+
// against the element's own size, which `ctx.em` is once the cascade has
|
|
4330
|
+
// settled it: a later rule's `font-size` outranks this one's, and
|
|
4331
|
+
// `font: 12px/150%` under a `font-size: 16px` is on 24px lines
|
|
4332
|
+
if (lineText) applyDeclaration(style, parent, 'line-height', lineText, ctx);
|
|
4007
4333
|
applyDeclaration(style, parent, 'font-family', family, ctx);
|
|
4008
4334
|
}
|
|
4009
4335
|
|
|
@@ -4723,6 +5049,7 @@ function camel(name: string): string {
|
|
|
4723
5049
|
|
|
4724
5050
|
const INHERITED_NAMES = new Set<string>([
|
|
4725
5051
|
'color',
|
|
5052
|
+
'color-scheme',
|
|
4726
5053
|
'-webkit-text-fill-color',
|
|
4727
5054
|
'font',
|
|
4728
5055
|
'font-family',
|
|
@@ -4773,6 +5100,11 @@ export function initialOne(
|
|
|
4773
5100
|
initial: ComputedStyle,
|
|
4774
5101
|
name: string,
|
|
4775
5102
|
): void {
|
|
5103
|
+
const list = MASK_LISTS[name];
|
|
5104
|
+
if (list) {
|
|
5105
|
+
style.mask = { ...style.mask, [list]: initial.mask[list] };
|
|
5106
|
+
return;
|
|
5107
|
+
}
|
|
4776
5108
|
const keys = INHERIT_TARGETS[name];
|
|
4777
5109
|
if (!keys) return;
|
|
4778
5110
|
for (const key of keys) {
|
|
@@ -4785,6 +5117,11 @@ function inheritOne(
|
|
|
4785
5117
|
parent: ComputedStyle,
|
|
4786
5118
|
name: string,
|
|
4787
5119
|
): void {
|
|
5120
|
+
const list = MASK_LISTS[name];
|
|
5121
|
+
if (list) {
|
|
5122
|
+
style.mask = { ...style.mask, [list]: parent.mask[list] };
|
|
5123
|
+
return;
|
|
5124
|
+
}
|
|
4788
5125
|
const keys = INHERIT_TARGETS[name];
|
|
4789
5126
|
if (!keys) return;
|
|
4790
5127
|
// A border colour left to `currentColor` inherits as the keyword and
|
|
@@ -4800,8 +5137,30 @@ const sides = (
|
|
|
4800
5137
|
make: (side: (typeof SIDES)[number]) => keyof ComputedStyle,
|
|
4801
5138
|
): (keyof ComputedStyle)[] => SIDES.map(make);
|
|
4802
5139
|
|
|
5140
|
+
/**
|
|
5141
|
+
* The list of the mask's layers each longhand is, which `initial`,
|
|
5142
|
+
* `inherit` and a `var()` that fails reset alone: one field holds them all,
|
|
5143
|
+
* and reset whole, a `mask-size: calc(var(--x) - 4px)` put back the
|
|
5144
|
+
* `mask-repeat: no-repeat` before it, and Wikipedia's chevron repeated.
|
|
5145
|
+
*/
|
|
5146
|
+
const MASK_LISTS: Record<string, keyof MaskLayers> = {
|
|
5147
|
+
'mask-image': 'images',
|
|
5148
|
+
'-webkit-mask-image': 'images',
|
|
5149
|
+
'mask-repeat': 'repeats',
|
|
5150
|
+
'-webkit-mask-repeat': 'repeats',
|
|
5151
|
+
'mask-size': 'sizes',
|
|
5152
|
+
'-webkit-mask-size': 'sizes',
|
|
5153
|
+
'mask-position': 'positions',
|
|
5154
|
+
'-webkit-mask-position': 'positions',
|
|
5155
|
+
'mask-origin': 'origins',
|
|
5156
|
+
'-webkit-mask-origin': 'origins',
|
|
5157
|
+
'mask-clip': 'clips',
|
|
5158
|
+
'-webkit-mask-clip': 'clips',
|
|
5159
|
+
};
|
|
5160
|
+
|
|
4803
5161
|
const INHERIT_TARGETS: Record<string, readonly (keyof ComputedStyle)[]> = {
|
|
4804
5162
|
color: ['color'],
|
|
5163
|
+
'color-scheme': ['colorScheme'],
|
|
4805
5164
|
'-webkit-text-fill-color': ['textFillColor'],
|
|
4806
5165
|
'background-clip': [
|
|
4807
5166
|
'backgroundClipText',
|
|
@@ -4815,6 +5174,8 @@ const INHERIT_TARGETS: Record<string, readonly (keyof ComputedStyle)[]> = {
|
|
|
4815
5174
|
],
|
|
4816
5175
|
'background-origin': ['backgroundOrigin', 'backgroundOrigins'],
|
|
4817
5176
|
'border-image': ['borderImage'],
|
|
5177
|
+
mask: ['mask'],
|
|
5178
|
+
'-webkit-mask': ['mask'],
|
|
4818
5179
|
'border-image-source': ['borderImage'],
|
|
4819
5180
|
'border-image-slice': ['borderImage'],
|
|
4820
5181
|
'border-image-width': ['borderImage'],
|
|
@@ -4895,6 +5256,8 @@ const INHERIT_TARGETS: Record<string, readonly (keyof ComputedStyle)[]> = {
|
|
|
4895
5256
|
'min-height': ['minHeight', 'minHeightKeyword'],
|
|
4896
5257
|
'max-height': ['maxHeight', 'maxHeightKeyword'],
|
|
4897
5258
|
'box-sizing': ['boxSizing'],
|
|
5259
|
+
'box-decoration-break': ['boxDecorationBreak'],
|
|
5260
|
+
'-webkit-box-decoration-break': ['boxDecorationBreak'],
|
|
4898
5261
|
margin: sides((s) => `margin${s}`),
|
|
4899
5262
|
'margin-top': ['marginTop'],
|
|
4900
5263
|
'margin-right': ['marginRight'],
|
package/src/html/css/ua.ts
CHANGED
|
@@ -44,8 +44,11 @@ export function uaStylesheet(look: RootLook): Stylesheet {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* Margins are in `em
|
|
48
|
-
* `body` scales its whitespace with its text the way a browser's does.
|
|
47
|
+
* Margins above and below are in `em`, so a document that sets `font-size`
|
|
48
|
+
* on `body` scales its whitespace with its text the way a browser's does.
|
|
49
|
+
* The indents of lists, definitions and figures are the HTML standard's
|
|
50
|
+
* 40px (15.3.3, 15.3.8), whatever the size: a list in a 10px sidebar is
|
|
51
|
+
* indented as far as one in the body.
|
|
49
52
|
*/
|
|
50
53
|
function uaText(look: RootLook): string {
|
|
51
54
|
const mono = look.monoFamily;
|
|
@@ -81,7 +84,7 @@ h4 { font-size: 1em; font-weight: bold; margin: 1.33em 0; }
|
|
|
81
84
|
h5 { font-size: 0.83em; font-weight: bold; margin: 1.67em 0; }
|
|
82
85
|
h6 { font-size: 0.67em; font-weight: bold; margin: 2.33em 0; }
|
|
83
86
|
|
|
84
|
-
ul, ol { margin: 1em 0; padding-left:
|
|
87
|
+
ul, ol { margin: 1em 0; padding-left: 40px; }
|
|
85
88
|
ul { list-style-type: disc; }
|
|
86
89
|
ol { list-style-type: decimal; }
|
|
87
90
|
ol, ul, menu, dir { counter-reset: list-item; }
|
|
@@ -92,7 +95,7 @@ ul ul ul, ol ol ul, ul ol ul, ol ul ul { list-style-type: square; }
|
|
|
92
95
|
ul ul, ul ol, ol ul, ol ol { margin: 0; }
|
|
93
96
|
|
|
94
97
|
dl { margin: 1em 0; }
|
|
95
|
-
dd { margin-left:
|
|
98
|
+
dd { margin-left: 40px; }
|
|
96
99
|
dt { font-weight: bold; }
|
|
97
100
|
|
|
98
101
|
blockquote {
|
|
@@ -150,7 +153,7 @@ img { display: inline-block; }
|
|
|
150
153
|
iframe { border: 2px inset; }
|
|
151
154
|
/* a poster is drawn within the video's box at its own ratio (HTML 15.4.1) */
|
|
152
155
|
video { object-fit: contain; }
|
|
153
|
-
figure { margin: 1em
|
|
156
|
+
figure { margin: 1em 40px; }
|
|
154
157
|
|
|
155
158
|
table { display: table; border-collapse: separate; border-spacing: 2px; box-sizing: border-box; }
|
|
156
159
|
caption { display: table-caption; text-align: center; }
|
|
@@ -185,6 +188,20 @@ input, button, select, textarea, meter, progress {
|
|
|
185
188
|
}
|
|
186
189
|
/* Chrome's own UA margins for the checkables, near enough: they are the
|
|
187
190
|
controls that sit hard against their label text otherwise. */
|
|
191
|
+
/* HTML's rendering section (15.3.10): a control's text keeps none of the
|
|
192
|
+
spacing, the line height, the case or the indent of the text around it.
|
|
193
|
+
A button in a paragraph of 'line-height: 1.5' is its own font's line
|
|
194
|
+
tall, as it is in a browser. */
|
|
195
|
+
input, button, textarea {
|
|
196
|
+
letter-spacing: initial;
|
|
197
|
+
word-spacing: initial;
|
|
198
|
+
line-height: initial;
|
|
199
|
+
}
|
|
200
|
+
input, select, button, textarea {
|
|
201
|
+
text-transform: initial;
|
|
202
|
+
text-indent: initial;
|
|
203
|
+
text-shadow: initial;
|
|
204
|
+
}
|
|
188
205
|
input[type=checkbox] { margin: 3px 4px 3px 4px; }
|
|
189
206
|
input[type=radio] { margin: 3px 4px 3px 5px; }
|
|
190
207
|
input[type=hidden] { display: none; }
|