@react-x11/components 0.13.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.
Files changed (128) hide show
  1. package/dist/html/controls.d.ts +29 -2
  2. package/dist/html/controls.d.ts.map +1 -1
  3. package/dist/html/controls.js +70 -2
  4. package/dist/html/controls.js.map +1 -1
  5. package/dist/html/css/cascade.d.ts.map +1 -1
  6. package/dist/html/css/cascade.js +26 -4
  7. package/dist/html/css/cascade.js.map +1 -1
  8. package/dist/html/css/color.d.ts +18 -0
  9. package/dist/html/css/color.d.ts.map +1 -1
  10. package/dist/html/css/color.js +27 -0
  11. package/dist/html/css/color.js.map +1 -1
  12. package/dist/html/css/parse.d.ts +18 -4
  13. package/dist/html/css/parse.d.ts.map +1 -1
  14. package/dist/html/css/parse.js +66 -28
  15. package/dist/html/css/parse.js.map +1 -1
  16. package/dist/html/css/style.d.ts +128 -15
  17. package/dist/html/css/style.d.ts.map +1 -1
  18. package/dist/html/css/style.js +561 -144
  19. package/dist/html/css/style.js.map +1 -1
  20. package/dist/html/css/transform.d.ts +85 -0
  21. package/dist/html/css/transform.d.ts.map +1 -0
  22. package/dist/html/css/transform.js +425 -0
  23. package/dist/html/css/transform.js.map +1 -0
  24. package/dist/html/css/ua.d.ts.map +1 -1
  25. package/dist/html/css/ua.js +14 -2
  26. package/dist/html/css/ua.js.map +1 -1
  27. package/dist/html/css/values.d.ts +4 -0
  28. package/dist/html/css/values.d.ts.map +1 -1
  29. package/dist/html/css/values.js.map +1 -1
  30. package/dist/html/fonts.d.ts +55 -5
  31. package/dist/html/fonts.d.ts.map +1 -1
  32. package/dist/html/fonts.js +284 -23
  33. package/dist/html/fonts.js.map +1 -1
  34. package/dist/html/layout/axes.d.ts +14 -0
  35. package/dist/html/layout/axes.d.ts.map +1 -0
  36. package/dist/html/layout/axes.js +28 -0
  37. package/dist/html/layout/axes.js.map +1 -0
  38. package/dist/html/layout/block.d.ts +93 -12
  39. package/dist/html/layout/block.d.ts.map +1 -1
  40. package/dist/html/layout/block.js +389 -39
  41. package/dist/html/layout/block.js.map +1 -1
  42. package/dist/html/layout/boxes.d.ts +59 -1
  43. package/dist/html/layout/boxes.d.ts.map +1 -1
  44. package/dist/html/layout/boxes.js +22 -2
  45. package/dist/html/layout/boxes.js.map +1 -1
  46. package/dist/html/layout/cache.d.ts +1 -1
  47. package/dist/html/layout/cache.d.ts.map +1 -1
  48. package/dist/html/layout/cache.js +6 -0
  49. package/dist/html/layout/cache.js.map +1 -1
  50. package/dist/html/layout/css-grid.d.ts.map +1 -1
  51. package/dist/html/layout/css-grid.js +90 -18
  52. package/dist/html/layout/css-grid.js.map +1 -1
  53. package/dist/html/layout/flex.d.ts.map +1 -1
  54. package/dist/html/layout/flex.js +570 -83
  55. package/dist/html/layout/flex.js.map +1 -1
  56. package/dist/html/layout/inline.d.ts +3 -0
  57. package/dist/html/layout/inline.d.ts.map +1 -1
  58. package/dist/html/layout/inline.js +144 -54
  59. package/dist/html/layout/inline.js.map +1 -1
  60. package/dist/html/layout/multicol.d.ts +42 -0
  61. package/dist/html/layout/multicol.d.ts.map +1 -0
  62. package/dist/html/layout/multicol.js +897 -0
  63. package/dist/html/layout/multicol.js.map +1 -0
  64. package/dist/html/layout/shaping.d.ts +7 -0
  65. package/dist/html/layout/shaping.d.ts.map +1 -1
  66. package/dist/html/layout/shaping.js +25 -20
  67. package/dist/html/layout/shaping.js.map +1 -1
  68. package/dist/html/layout/table.d.ts.map +1 -1
  69. package/dist/html/layout/table.js +62 -18
  70. package/dist/html/layout/table.js.map +1 -1
  71. package/dist/html/node.d.ts +3 -0
  72. package/dist/html/node.d.ts.map +1 -1
  73. package/dist/html/node.js +263 -36
  74. package/dist/html/node.js.map +1 -1
  75. package/dist/html/paint.d.ts +79 -4
  76. package/dist/html/paint.d.ts.map +1 -1
  77. package/dist/html/paint.js +1213 -141
  78. package/dist/html/paint.js.map +1 -1
  79. package/dist/html/svg.d.ts +15 -2
  80. package/dist/html/svg.d.ts.map +1 -1
  81. package/dist/html/svg.js +249 -17
  82. package/dist/html/svg.js.map +1 -1
  83. package/dist/html/widgets.js +87 -7
  84. package/dist/html/widgets.js.map +1 -1
  85. package/dist/html/woff2.d.ts +14 -0
  86. package/dist/html/woff2.d.ts.map +1 -0
  87. package/dist/html/woff2.js +608 -0
  88. package/dist/html/woff2.js.map +1 -0
  89. package/dist/maps/controller.d.ts +17 -1
  90. package/dist/maps/controller.d.ts.map +1 -1
  91. package/dist/maps/controller.js +27 -7
  92. package/dist/maps/controller.js.map +1 -1
  93. package/dist/richtext/node.d.ts +8 -1
  94. package/dist/richtext/node.d.ts.map +1 -1
  95. package/dist/richtext/node.js +5 -1
  96. package/dist/richtext/node.js.map +1 -1
  97. package/dist/richtext/runs.d.ts +25 -6
  98. package/dist/richtext/runs.d.ts.map +1 -1
  99. package/dist/richtext/runs.js +240 -24
  100. package/dist/richtext/runs.js.map +1 -1
  101. package/package.json +1 -1
  102. package/src/html/controls.ts +85 -2
  103. package/src/html/css/cascade.ts +23 -0
  104. package/src/html/css/color.ts +29 -0
  105. package/src/html/css/parse.ts +71 -31
  106. package/src/html/css/style.ts +664 -147
  107. package/src/html/css/transform.ts +459 -0
  108. package/src/html/css/ua.ts +15 -2
  109. package/src/html/css/values.ts +4 -0
  110. package/src/html/fonts.ts +312 -29
  111. package/src/html/layout/axes.ts +62 -0
  112. package/src/html/layout/block.ts +444 -37
  113. package/src/html/layout/boxes.ts +65 -3
  114. package/src/html/layout/cache.ts +6 -0
  115. package/src/html/layout/css-grid.ts +95 -22
  116. package/src/html/layout/flex.ts +671 -77
  117. package/src/html/layout/inline.ts +149 -55
  118. package/src/html/layout/multicol.ts +977 -0
  119. package/src/html/layout/shaping.ts +27 -18
  120. package/src/html/layout/table.ts +62 -19
  121. package/src/html/node.ts +300 -37
  122. package/src/html/paint.ts +1406 -206
  123. package/src/html/svg.ts +277 -19
  124. package/src/html/widgets.ts +95 -9
  125. package/src/html/woff2.ts +612 -0
  126. package/src/maps/controller.ts +28 -7
  127. package/src/richtext/node.ts +13 -2
  128. package/src/richtext/runs.ts +313 -35
@@ -47,29 +47,38 @@ export function shapingSafe(engine: FontsLike): FontsLike {
47
47
  return engine.layout(stood.content, style, options);
48
48
  }
49
49
  };
50
- // Everything else the engine answers is its own, called on it: `match`,
51
- // and what a caller feature-detects — ntk's `prewarm`, which
52
- // `_warmFaces` asks for — where a wrapper that forwarded only the two
53
- // it knew of hid the rest, and warming stopped without a word.
54
- const bound = new Map<PropertyKey, { from: unknown; to: unknown }>();
55
- safe = new Proxy(engine, {
56
- get(target, key) {
57
- if (key === 'layout') return layout;
58
- const value: unknown = Reflect.get(target, key, target);
59
- if (typeof value !== 'function') return value;
60
- let hit = bound.get(key);
61
- if (hit?.from !== value) {
62
- hit = { from: value, to: value.bind(target) };
63
- bound.set(key, hit);
64
- }
65
- return hit.to;
66
- },
67
- });
50
+ safe = withLayout(engine, layout);
68
51
  SAFE.set(engine, safe);
69
52
  }
70
53
  return safe;
71
54
  }
72
55
 
56
+ /**
57
+ * `engine` with another `layout`. Everything else the engine answers is its
58
+ * own, called on it: `match`, and what a caller feature-detects — ntk's
59
+ * `prewarm`, which `_warmFaces` asks for — where a wrapper that forwarded
60
+ * only the two it knew of hid the rest, and warming stopped without a word.
61
+ */
62
+ export function withLayout(
63
+ engine: FontsLike,
64
+ layout: FontsLike['layout'],
65
+ ): FontsLike {
66
+ const bound = new Map<PropertyKey, { from: unknown; to: unknown }>();
67
+ return new Proxy(engine, {
68
+ get(target, key) {
69
+ if (key === 'layout') return layout;
70
+ const value: unknown = Reflect.get(target, key, target);
71
+ if (typeof value !== 'function') return value;
72
+ let hit = bound.get(key);
73
+ if (hit?.from !== value) {
74
+ hit = { from: value, to: value.bind(target) };
75
+ bound.set(key, hit);
76
+ }
77
+ return hit.to;
78
+ },
79
+ });
80
+ }
81
+
73
82
  /** `content` with each character its face cannot shape replaced, or null
74
83
  * when there is none to replace. */
75
84
  function standIns(
@@ -13,11 +13,13 @@
13
13
  // algorithm is too slow — which, on a table with a thousand rows, it is.
14
14
  import { AUTO, isPct, resolveOrNull } from '../css/values.js';
15
15
  import type { Len } from '../css/values.js';
16
+ import type { ComputedStyle } from '../css/style.js';
16
17
  import { Box, CLIPPED_CELLS, COLLAPSED_CELLS, isBlank } from './boxes.js';
17
18
  import {
18
19
  CELL_CONTENT,
19
20
  MIN_CONTENT_PROBE,
20
21
  clampHeight,
22
+ cyclicWidth,
21
23
  exactMinContent,
22
24
  layoutBlockIn,
23
25
  measureIntrinsicWidth,
@@ -40,12 +42,16 @@ export function layoutTable(
40
42
  tableGrid(table);
41
43
  table.captionTop = 0;
42
44
  table.captionBottom = 0;
45
+ // a percentage of a width that is not known is `auto`: the table is as
46
+ // wide as its columns where its content is measured (`cyclicWidth`)
47
+ const auto =
48
+ table.style.width === AUTO || cyclicWidth(table.style, contentWidth);
43
49
  if (!columnCount) {
44
50
  // With no columns, an auto table is as wide as its widest caption can
45
51
  // be and its `min-width` asks, as one with columns is at the least
46
52
  // (17.5.2), rather than as the room on offer: a caption over no cells
47
53
  // was centred in the width of the page.
48
- if (table.style.width === AUTO) {
54
+ if (auto) {
49
55
  let inner = captions.length
50
56
  ? captionMinimum(captions, ctx) - table.horizontalExtra
51
57
  : 0;
@@ -72,11 +78,18 @@ export function layoutTable(
72
78
  const gaps = spacing * (columnCount + 1);
73
79
  const available = Math.max(0, contentWidth - gaps);
74
80
 
75
- for (const cell of cells) resolveEdges(cell.box, contentWidth);
81
+ // While the columns are sized, a percentage in a cell's padding is of
82
+ // nothing: the width it is of is the one the columns are being sized to
83
+ // come to (CSS Sizing 3, 5.2.1), and a cell asks of its column what its
84
+ // content does. It is a share of the row once the columns have their
85
+ // widths, below. Taken of the table's width here, and of the cell's own
86
+ // where the cell was laid out, a padded cell's column was wider than
87
+ // its share and its padding narrower.
88
+ for (const cell of cells) resolveEdges(cell.box, 0);
76
89
 
77
90
  // a fixed layout needs a width to be fixed to; with `auto` a table is laid
78
91
  // out by its contents after all (CSS 2.1 17.5.2.1)
79
- const fixed = style.tableLayout === 'fixed' && style.width !== AUTO;
92
+ const fixed = style.tableLayout === 'fixed' && !auto;
80
93
  // a percentage of the table's width less its spacing (CSS 2.1 17.5.2.1)
81
94
  const set = columnWidths(columnBoxes, columnGroups, available);
82
95
  const widths = fixed
@@ -88,14 +101,14 @@ export function layoutTable(
88
101
  available,
89
102
  ctx,
90
103
  contentWidth,
91
- style.width !== AUTO,
104
+ !auto,
92
105
  spacing,
93
106
  );
94
107
 
95
108
  // --- place ---------------------------------------------------------------
96
109
  // An auto table is at least as wide as its widest caption can be (CSS 2.1
97
110
  // 17.5.2), and as its `min-width` asks; the columns share what that adds.
98
- if (style.width === AUTO) {
111
+ if (auto) {
99
112
  let room = 0;
100
113
  if (captions.length) {
101
114
  room = captionMinimum(captions, ctx) - table.horizontalExtra - gaps;
@@ -145,7 +158,7 @@ export function layoutTable(
145
158
  // gives its room back either way, set width or not.
146
159
  const used = x - table.contentX;
147
160
  let tableContentWidth = contentWidth;
148
- if (style.width === AUTO) {
161
+ if (auto) {
149
162
  tableContentWidth = used;
150
163
  table.width = tableContentWidth + table.horizontalExtra;
151
164
  } else if (used > contentWidth || anyGone) {
@@ -164,11 +177,21 @@ export function layoutTable(
164
177
  // tallest cell in it rather than the first one that was measured. What
165
178
  // its content came to is kept apart from a height the cell sets: it is
166
179
  // that content `vertical-align` moves in the cell.
180
+ //
181
+ // A percentage in a cell's padding is of the width of its row: the
182
+ // columns and the spacing between them, without the spacing either side
183
+ // and the table's own padding. CSS 2.1 8.4 has it of the containing
184
+ // block's width and names none for a cell; the row's is what browsers
185
+ // take, and what the table's content box is wherever there is no
186
+ // spacing. Every column counts, one `visibility: collapse` takes out
187
+ // too, so that taking it out changes no row's height.
188
+ let rowWidth = spacing * Math.max(0, columnCount - 1);
189
+ for (const columnWidth of widths) rowWidth += columnWidth;
167
190
  const natural: number[] = new Array<number>(cells.length);
168
191
  for (let i = 0; i < cells.length; i += 1) {
169
192
  const cell = cells[i];
170
193
  const width = spannedWidth(widths, cell, spacing);
171
- ctx.layoutSubtree(cell.box, width);
194
+ ctx.layoutSubtree(cell.box, width, rowWidth);
172
195
  natural[i] = CELL_CONTENT.get(cell.box) ?? cell.box.height;
173
196
  // A height a cell sets is a least one: its content is laid out as a
174
197
  // block's, which keeps a height it sets and lets the content run out of
@@ -303,7 +326,9 @@ export function layoutTable(
303
326
  // `vertical-align` inside a cell moves the *content*, not the box: the
304
327
  // box fills the row, background and all, and the content sits top,
305
328
  // middle, bottom or on the row's baseline in it — in the box a height
306
- // of its own makes too, which is no content to be moved
329
+ // of its own makes too, which is no content to be moved. The cell was
330
+ // laid out above, in this pass over the cells, so this is the one move
331
+ // its content and its static positions get (`moveContent`)
307
332
  let offset = lift[i];
308
333
  const va = cell.box.style.verticalAlign;
309
334
  const content = natural[i];
@@ -462,7 +487,7 @@ function fixedColumns(
462
487
  }
463
488
  for (const cell of cells) {
464
489
  if (cell.row > 0) break;
465
- const px = tableWidth(cell.box.style.width, available);
490
+ const px = ownWidth(cell.box.style, available);
466
491
  if (px === null) continue;
467
492
  const box = cell.box;
468
493
  const outer =
@@ -706,14 +731,14 @@ function columnWidths(
706
731
  }
707
732
 
708
733
  /** A column's or a column group's width, within its limits, or null where
709
- * it sets none. */
734
+ * it sets none. The limits are lengths: a percentage in them does what it
735
+ * does in a cell's (`cellWidth`). */
710
736
  function partWidth(box: Box, base: number): number | null {
711
737
  const style = box.style;
712
- const width = tableWidth(style.width, base);
713
- const min = lengthAgainst(style.minWidth, base) ?? 0;
738
+ const width = ownWidth(style, base);
739
+ const min = typeof style.minWidth === 'number' ? style.minWidth : 0;
714
740
  if (width === null && !(min > 0)) return null;
715
- const max =
716
- style.maxWidth === 'none' ? null : lengthAgainst(style.maxWidth, base);
741
+ const max = typeof style.maxWidth === 'number' ? style.maxWidth : null;
717
742
  let out = width ?? 0;
718
743
  if (max !== null) out = Math.min(out, max);
719
744
  return Math.max(0, out, min);
@@ -726,15 +751,20 @@ function partWidth(box: Box, base: number): number | null {
726
751
  * `min-width` and `max-width` as a column's is (`partWidth`), which CSS
727
752
  * 2.1 leaves undefined and every browser does: a cell set `width: 3in;
728
753
  * max-width: 1in` is an inch wide, and one with `min-width` alone is as
729
- * wide as that. */
754
+ * wide as that.
755
+ *
756
+ * Where they are lengths. A percentage `min-width` is ignored, and a
757
+ * percentage `max-width` holds a percentage `width` and nothing else
758
+ * (CSS Tables 3, 3.8.2, and `ownWidth`): a cell `width: 100px;
759
+ * max-width: 10%` in a table of 600 is 100 wide, where it was 60, and
760
+ * one set `min-width: 150%` takes no more than its content asks. */
730
761
  function cellWidth(cell: Cell, base: number): number | null {
731
762
  const style = cell.box.style;
732
763
  const len = style.width;
733
- const width = len === AUTO ? null : tableWidth(len, base);
734
- const min = lengthAgainst(style.minWidth, base) ?? 0;
764
+ const width = ownWidth(style, base);
765
+ const min = typeof style.minWidth === 'number' ? style.minWidth : 0;
735
766
  if (width === null && !(min > 0)) return null;
736
- const max =
737
- style.maxWidth === 'none' ? null : lengthAgainst(style.maxWidth, base);
767
+ const max = typeof style.maxWidth === 'number' ? style.maxWidth : null;
738
768
  let own = width ?? 0;
739
769
  if (max !== null) own = Math.min(own, max);
740
770
  own = Math.max(0, own, min);
@@ -744,6 +774,19 @@ function cellWidth(cell: Cell, base: number): number | null {
744
774
  return own + cell.box.horizontalExtra;
745
775
  }
746
776
 
777
+ /** A cell's, a column's or a column group's `width` as the columns read
778
+ * it, or null: a percentage no more than a percentage its `max-width` is
779
+ * — the percentage each contributes is `min(percentage width, percentage
780
+ * max-width)`, a `max-width` that is no percentage counting as an
781
+ * infinite one (CSS Tables 3, 3.8.2). */
782
+ function ownWidth(style: ComputedStyle, base: number): number | null {
783
+ const width = tableWidth(style.width, base);
784
+ const limit = style.maxWidth;
785
+ if (width === null || !isPct(style.width)) return width;
786
+ if (limit === 'none' || !isPct(limit) || limit.px || limit.of) return width;
787
+ return Math.min(width, lengthAgainst(limit, base) ?? width);
788
+ }
789
+
747
790
  /** A cell's or a column's width. One that adds a percentage to a length,
748
791
  * a `calc()`, is `auto` in a table, as browsers read it: a column cannot be
749
792
  * both a share of the table and a size of its own. */