@promptctl/rich-js 0.28.0 → 0.29.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/README.md +7 -7
- package/dist/core/animation.d.ts +37 -37
- package/dist/core/animation.js +61 -61
- package/dist/core/ansi.d.ts +4 -4
- package/dist/core/ansi.js +9 -9
- package/dist/core/bidi.js +6 -6
- package/dist/core/cells.d.ts +1 -1
- package/dist/core/cells.js +5 -5
- package/dist/core/clock.d.ts +1 -1
- package/dist/core/color.d.ts +50 -50
- package/dist/core/color.js +69 -69
- package/dist/core/console.d.ts +8 -8
- package/dist/core/console.js +5 -5
- package/dist/core/control-codes.d.ts +3 -3
- package/dist/core/control-codes.js +7 -7
- package/dist/core/easing.d.ts +40 -40
- package/dist/core/easing.js +40 -40
- package/dist/core/env.d.ts +1 -1
- package/dist/core/env.js +1 -1
- package/dist/core/export-html.js +1 -1
- package/dist/core/export-lines.d.ts +11 -11
- package/dist/core/export-lines.js +12 -12
- package/dist/core/export-svg.d.ts +3 -3
- package/dist/core/export-svg.js +4 -4
- package/dist/core/markup.js +1 -1
- package/dist/core/memo.d.ts +1 -1
- package/dist/core/memo.js +1 -1
- package/dist/core/oklch.d.ts +14 -14
- package/dist/core/oklch.js +10 -10
- package/dist/core/orient.d.ts +3 -3
- package/dist/core/orient.js +3 -3
- package/dist/core/paint.d.ts +9 -9
- package/dist/core/paint.js +3 -3
- package/dist/core/pretty.d.ts +1 -1
- package/dist/core/pretty.js +3 -3
- package/dist/core/protocol.d.ts +26 -26
- package/dist/core/protocol.js +22 -22
- package/dist/core/render.d.ts +11 -11
- package/dist/core/render.js +12 -12
- package/dist/core/segment.d.ts +3 -3
- package/dist/core/segment.js +5 -5
- package/dist/core/strip.d.ts +83 -83
- package/dist/core/strip.js +70 -70
- package/dist/core/style.d.ts +20 -20
- package/dist/core/style.js +55 -55
- package/dist/core/text.d.ts +2 -2
- package/dist/core/text.js +5 -5
- package/dist/core/timeline.d.ts +5 -5
- package/dist/core/timeline.js +9 -9
- package/dist/core/tween.d.ts +6 -6
- package/dist/core/tween.js +10 -10
- package/dist/core/view.d.ts +4 -4
- package/dist/core/view.js +12 -12
- package/dist/host/app.d.ts +9 -9
- package/dist/host/app.js +12 -12
- package/dist/host/host-environment.d.ts +2 -2
- package/dist/host/host-environment.js +2 -2
- package/dist/host/index.d.ts +2 -2
- package/dist/host/input.d.ts +7 -7
- package/dist/host/input.js +4 -4
- package/dist/host/terminal-colors.d.ts +2 -2
- package/dist/host/terminal-colors.js +4 -4
- package/dist/host/terminal-host.d.ts +2 -2
- package/dist/host/terminal-host.js +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.js +10 -10
- package/dist/node/prompt.d.ts +1 -1
- package/dist/node/prompt.js +1 -1
- package/dist/node/terminal-host.d.ts +1 -1
- package/dist/node/traceback.js +2 -2
- package/dist/renderables/change.js +2 -2
- package/dist/renderables/effect.d.ts +39 -39
- package/dist/renderables/effect.js +45 -45
- package/dist/renderables/effects.d.ts +81 -81
- package/dist/renderables/effects.js +157 -157
- package/dist/renderables/embed.d.ts +1 -1
- package/dist/renderables/embed.js +2 -2
- package/dist/renderables/flexStrip.d.ts +7 -7
- package/dist/renderables/flexStrip.js +15 -15
- package/dist/renderables/frames.d.ts +6 -6
- package/dist/renderables/frames.js +11 -11
- package/dist/renderables/glyph-effect.d.ts +15 -15
- package/dist/renderables/glyph-effect.js +17 -17
- package/dist/renderables/glyph-effects.d.ts +7 -7
- package/dist/renderables/glyph-effects.js +16 -16
- package/dist/renderables/html-entities.d.ts +1 -1
- package/dist/renderables/html-entities.js +1 -1
- package/dist/renderables/lifecycle.d.ts +4 -4
- package/dist/renderables/lifecycle.js +12 -12
- package/dist/renderables/live.d.ts +2 -2
- package/dist/renderables/live.js +7 -7
- package/dist/renderables/markdown-parse.js +3 -3
- package/dist/renderables/panel.js +3 -3
- package/dist/renderables/progress.d.ts +1 -1
- package/dist/renderables/progress.js +1 -1
- package/dist/renderables/progressBar.d.ts +1 -1
- package/dist/renderables/progressBar.js +6 -6
- package/dist/renderables/prompt.d.ts +1 -1
- package/dist/renderables/scroll.d.ts +1 -1
- package/dist/renderables/scroll.js +3 -3
- package/dist/renderables/spinner.d.ts +4 -4
- package/dist/renderables/spinner.js +10 -10
- package/dist/renderables/syntax.d.ts +2 -2
- package/dist/renderables/syntax.js +2 -2
- package/dist/renderables/table.js +3 -3
- package/dist/renderables/traceback.d.ts +1 -1
- package/dist/renderables/traceback.js +1 -1
- package/dist/renderables/tree.js +3 -3
- package/dist/template-bindings/animation-funcs.d.ts +14 -14
- package/dist/template-bindings/animation-funcs.js +27 -27
- package/dist/template-bindings/color-funcs.d.ts +14 -14
- package/dist/template-bindings/color-funcs.js +25 -25
- package/dist/template-bindings/index.d.ts +9 -9
- package/dist/template-bindings/index.js +9 -9
- package/dist/template-bindings/palette-funcs.d.ts +1 -1
- package/dist/template-bindings/palette-funcs.js +3 -3
- package/dist/template-bindings/style-funcs.d.ts +5 -5
- package/dist/template-bindings/style-funcs.js +16 -16
- package/dist/themes/{transpose.d.ts → adjust.d.ts} +23 -23
- package/dist/themes/{transpose.js → adjust.js} +28 -28
- package/dist/themes/buildPalette.d.ts +3 -3
- package/dist/themes/buildPalette.js +20 -20
- package/dist/themes/colorMath.d.ts +16 -16
- package/dist/themes/colorMath.js +32 -32
- package/dist/themes/data/ansi-tables.d.ts +2 -2
- package/dist/themes/data/ansi-tables.js +2 -2
- package/dist/themes/data/types.d.ts +4 -4
- package/dist/themes/data/types.js +2 -2
- package/dist/themes/palette.d.ts +12 -12
- package/dist/themes/palette.js +16 -16
- package/dist/themes/ramp.d.ts +17 -17
- package/dist/themes/ramp.js +12 -12
- package/dist/themes/registry.js +4 -4
- package/dist/themes/terminalThemes.d.ts +1 -1
- package/dist/themes/terminalThemes.js +1 -1
- package/dist/widgets/button.d.ts +2 -2
- package/dist/widgets/button.js +4 -4
- package/dist/widgets/checkbox.d.ts +2 -2
- package/dist/widgets/checkbox.js +2 -2
- package/dist/widgets/dropdown.d.ts +2 -2
- package/dist/widgets/dropdown.js +3 -3
- package/dist/widgets/event-router.d.ts +6 -6
- package/dist/widgets/event-router.js +2 -2
- package/dist/widgets/focus-manager.d.ts +3 -3
- package/dist/widgets/focus-manager.js +3 -3
- package/dist/widgets/index.d.ts +2 -2
- package/dist/widgets/index.js +1 -1
- package/dist/widgets/ink.d.ts +3 -3
- package/dist/widgets/ink.js +4 -4
- package/dist/widgets/slider.d.ts +2 -2
- package/dist/widgets/static-item.d.ts +2 -2
- package/dist/widgets/text-input.d.ts +2 -2
- package/dist/widgets/text-input.js +5 -5
- package/dist/widgets/themed-widget.js +1 -1
- package/dist/widgets/toggle.d.ts +3 -3
- package/dist/widgets/toggle.js +3 -3
- package/dist/widgets/types.d.ts +6 -6
- package/dist/widgets/types.js +2 -2
- package/dist/widgets/widget-app.d.ts +10 -10
- package/dist/widgets/widget-app.js +8 -8
- package/dist/widgets/widget-base.d.ts +2 -2
- package/package.json +1 -1
package/dist/core/style.js
CHANGED
|
@@ -6,7 +6,7 @@ import { shiftAnchor } from "./anchor.js";
|
|
|
6
6
|
import { Memo } from "./memo.js";
|
|
7
7
|
import { pattern } from "./pattern.js";
|
|
8
8
|
// [LAW:one-way-deps] `core/style` depends only on `core/color`. The substrate
|
|
9
|
-
// a translucent
|
|
9
|
+
// a translucent color is flattened over is `SURFACE_BLACK`, defined beside
|
|
10
10
|
// `compositeOver`.
|
|
11
11
|
// --- Attribute definitions ---
|
|
12
12
|
/**
|
|
@@ -21,11 +21,11 @@ export const ATTRIBUTE_NAMES = [
|
|
|
21
21
|
"italic",
|
|
22
22
|
"underline",
|
|
23
23
|
"blink",
|
|
24
|
-
"
|
|
24
|
+
"rapidBlink",
|
|
25
25
|
"reverse",
|
|
26
26
|
"conceal",
|
|
27
27
|
"strike",
|
|
28
|
-
"
|
|
28
|
+
"doubleUnderline",
|
|
29
29
|
"frame",
|
|
30
30
|
"encircle",
|
|
31
31
|
"overline",
|
|
@@ -37,11 +37,11 @@ export const ATTRIBUTE_SGR = {
|
|
|
37
37
|
italic: 3,
|
|
38
38
|
underline: 4,
|
|
39
39
|
blink: 5,
|
|
40
|
-
|
|
40
|
+
rapidBlink: 6,
|
|
41
41
|
reverse: 7,
|
|
42
42
|
conceal: 8,
|
|
43
43
|
strike: 9,
|
|
44
|
-
|
|
44
|
+
doubleUnderline: 21,
|
|
45
45
|
frame: 51,
|
|
46
46
|
encircle: 52,
|
|
47
47
|
overline: 53,
|
|
@@ -60,13 +60,13 @@ export const ATTRIBUTE_SHORT_ALIASES = {
|
|
|
60
60
|
s: "strike",
|
|
61
61
|
r: "reverse",
|
|
62
62
|
o: "overline",
|
|
63
|
-
uu: "
|
|
63
|
+
uu: "doubleUnderline",
|
|
64
64
|
};
|
|
65
65
|
/** The hold of a cell that never changes: always was, and always will be. */
|
|
66
|
-
export const NEVER_CHANGES = {
|
|
67
|
-
/** The moments both `a` and `b` hold through: the later `
|
|
66
|
+
export const NEVER_CHANGES = { validFrom: Number.NEGATIVE_INFINITY, validUntil: Number.POSITIVE_INFINITY };
|
|
67
|
+
/** The moments both `a` and `b` hold through: the later `validFrom` and the sooner `validUntil`. */
|
|
68
68
|
export function intersection(a, b) {
|
|
69
|
-
return {
|
|
69
|
+
return { validFrom: Math.max(a.validFrom, b.validFrom), validUntil: Math.min(a.validUntil, b.validUntil) };
|
|
70
70
|
}
|
|
71
71
|
export class StyleSyntaxError extends Error {
|
|
72
72
|
constructor(message, options) {
|
|
@@ -85,11 +85,11 @@ export class Style {
|
|
|
85
85
|
italic;
|
|
86
86
|
underline;
|
|
87
87
|
blink;
|
|
88
|
-
|
|
88
|
+
rapidBlink;
|
|
89
89
|
reverse;
|
|
90
90
|
conceal;
|
|
91
91
|
strike;
|
|
92
|
-
|
|
92
|
+
doubleUnderline;
|
|
93
93
|
frame;
|
|
94
94
|
encircle;
|
|
95
95
|
overline;
|
|
@@ -120,30 +120,30 @@ export class Style {
|
|
|
120
120
|
bidi;
|
|
121
121
|
/**
|
|
122
122
|
* The hold this style's cells are in, on the timeline of whoever drew the
|
|
123
|
-
* frame: since when what they show has been what it is (`
|
|
124
|
-
* when it next changes (`
|
|
123
|
+
* frame: since when what they show has been what it is (`validFrom`), and
|
|
124
|
+
* when it next changes (`validUntil`) — both `t` for a cell drawn by
|
|
125
125
|
* something that moves every frame, and `-Infinity`/`Infinity` for one
|
|
126
126
|
* that never changes. It draws nothing. Whatever draws for a handed time
|
|
127
127
|
* stamps its cells with it (`placedRender`, `Effected`), the stamp rides up
|
|
128
128
|
* through every container as the anchor does (`./anchor.ts`), and whoever
|
|
129
|
-
* holds the composed frame reads it off (`Segment.
|
|
130
|
-
* `Segment.
|
|
129
|
+
* holds the composed frame reads it off (`Segment.validUntil`, and
|
|
130
|
+
* `Segment.validFrom` for a host running its timeline backwards), so a
|
|
131
131
|
* host knows when to draw again without asking each container. Two styles
|
|
132
132
|
* laid together are in the intersection of their holds.
|
|
133
133
|
*/
|
|
134
|
-
|
|
134
|
+
validity;
|
|
135
135
|
constructor(options = {}) {
|
|
136
|
-
const
|
|
137
|
-
const {
|
|
136
|
+
const validity = options.validity ?? NEVER_CHANGES;
|
|
137
|
+
const { validFrom, validUntil } = validity;
|
|
138
138
|
// [LAW:parse-dont-validate] A time or never, settled where the style is
|
|
139
139
|
// made: NaN and the far infinity fail here, so no reader of a frame meets one.
|
|
140
|
-
if (!(
|
|
141
|
-
throw new RangeError(`Style
|
|
140
|
+
if (!(validUntil > Number.NEGATIVE_INFINITY)) {
|
|
141
|
+
throw new RangeError(`Style validUntil must be a time in seconds or Infinity, got ${validUntil}`);
|
|
142
142
|
}
|
|
143
|
-
if (!(
|
|
144
|
-
throw new RangeError(`Style
|
|
143
|
+
if (!(validFrom < Number.POSITIVE_INFINITY)) {
|
|
144
|
+
throw new RangeError(`Style validFrom must be a time in seconds or -Infinity, got ${validFrom}`);
|
|
145
145
|
}
|
|
146
|
-
this.
|
|
146
|
+
this.validity = validity;
|
|
147
147
|
this.color = resolveColor(options.color);
|
|
148
148
|
this.bgcolor = resolveBackground(options.bgcolor);
|
|
149
149
|
this.bold = options.bold;
|
|
@@ -151,11 +151,11 @@ export class Style {
|
|
|
151
151
|
this.italic = options.italic;
|
|
152
152
|
this.underline = options.underline;
|
|
153
153
|
this.blink = options.blink;
|
|
154
|
-
this.
|
|
154
|
+
this.rapidBlink = options.rapidBlink;
|
|
155
155
|
this.reverse = options.reverse;
|
|
156
156
|
this.conceal = options.conceal;
|
|
157
157
|
this.strike = options.strike;
|
|
158
|
-
this.
|
|
158
|
+
this.doubleUnderline = options.doubleUnderline;
|
|
159
159
|
this.frame = options.frame;
|
|
160
160
|
this.encircle = options.encircle;
|
|
161
161
|
this.overline = options.overline;
|
|
@@ -174,11 +174,11 @@ export class Style {
|
|
|
174
174
|
this.italic === undefined &&
|
|
175
175
|
this.underline === undefined &&
|
|
176
176
|
this.blink === undefined &&
|
|
177
|
-
this.
|
|
177
|
+
this.rapidBlink === undefined &&
|
|
178
178
|
this.reverse === undefined &&
|
|
179
179
|
this.conceal === undefined &&
|
|
180
180
|
this.strike === undefined &&
|
|
181
|
-
this.
|
|
181
|
+
this.doubleUnderline === undefined &&
|
|
182
182
|
this.frame === undefined &&
|
|
183
183
|
this.encircle === undefined &&
|
|
184
184
|
this.overline === undefined &&
|
|
@@ -187,8 +187,8 @@ export class Style {
|
|
|
187
187
|
this.anchor === undefined &&
|
|
188
188
|
this.boxFrame === undefined &&
|
|
189
189
|
this.bidi === undefined &&
|
|
190
|
-
this.
|
|
191
|
-
this.
|
|
190
|
+
this.validity.validUntil === Number.POSITIVE_INFINITY &&
|
|
191
|
+
this.validity.validFrom === Number.NEGATIVE_INFINITY);
|
|
192
192
|
}
|
|
193
193
|
get transparentBackground() {
|
|
194
194
|
return this.bgcolor === undefined || this.bgcolor.isDefault;
|
|
@@ -243,16 +243,16 @@ export class Style {
|
|
|
243
243
|
*/
|
|
244
244
|
withAttributes(attributes) {
|
|
245
245
|
// Only the attribute names are read: a wider object — a `Style`, say —
|
|
246
|
-
// satisfies the type and must not carry its
|
|
246
|
+
// satisfies the type and must not carry its colors or anchor in with it.
|
|
247
247
|
return this.with(Object.fromEntries(ATTRIBUTE_NAMES.filter((name) => name in attributes).map((name) => [name, attributes[name]])));
|
|
248
248
|
}
|
|
249
249
|
/**
|
|
250
250
|
* This style with its motion taken out, what reduced motion draws: `blink`
|
|
251
|
-
* and `
|
|
251
|
+
* and `rapidBlink`, the motion a terminal makes on its own, unset, and every
|
|
252
252
|
* other field as it was. A style that does not blink is its own.
|
|
253
253
|
*/
|
|
254
254
|
reduced() {
|
|
255
|
-
return this.blink || this.
|
|
255
|
+
return this.blink || this.rapidBlink ? this.withAttributes({ blink: undefined, rapidBlink: undefined }) : this;
|
|
256
256
|
}
|
|
257
257
|
/**
|
|
258
258
|
* This style on the cell `cells` to the right: its anchor shifted along its
|
|
@@ -277,11 +277,11 @@ export class Style {
|
|
|
277
277
|
italic: other.italic ?? this.italic,
|
|
278
278
|
underline: other.underline ?? this.underline,
|
|
279
279
|
blink: other.blink ?? this.blink,
|
|
280
|
-
|
|
280
|
+
rapidBlink: other.rapidBlink ?? this.rapidBlink,
|
|
281
281
|
reverse: other.reverse ?? this.reverse,
|
|
282
282
|
conceal: other.conceal ?? this.conceal,
|
|
283
283
|
strike: other.strike ?? this.strike,
|
|
284
|
-
|
|
284
|
+
doubleUnderline: other.doubleUnderline ?? this.doubleUnderline,
|
|
285
285
|
frame: other.frame ?? this.frame,
|
|
286
286
|
encircle: other.encircle ?? this.encircle,
|
|
287
287
|
overline: other.overline ?? this.overline,
|
|
@@ -293,7 +293,7 @@ export class Style {
|
|
|
293
293
|
boxFrame: other.boxFrame ?? this.boxFrame,
|
|
294
294
|
bidi: other.bidi ?? this.bidi,
|
|
295
295
|
// Cells under both change when either does.
|
|
296
|
-
|
|
296
|
+
validity: intersection(this.validity, other.validity),
|
|
297
297
|
});
|
|
298
298
|
}
|
|
299
299
|
equals(other) {
|
|
@@ -306,11 +306,11 @@ export class Style {
|
|
|
306
306
|
this.italic === other.italic &&
|
|
307
307
|
this.underline === other.underline &&
|
|
308
308
|
this.blink === other.blink &&
|
|
309
|
-
this.
|
|
309
|
+
this.rapidBlink === other.rapidBlink &&
|
|
310
310
|
this.reverse === other.reverse &&
|
|
311
311
|
this.conceal === other.conceal &&
|
|
312
312
|
this.strike === other.strike &&
|
|
313
|
-
this.
|
|
313
|
+
this.doubleUnderline === other.doubleUnderline &&
|
|
314
314
|
this.frame === other.frame &&
|
|
315
315
|
this.encircle === other.encircle &&
|
|
316
316
|
this.overline === other.overline &&
|
|
@@ -318,11 +318,11 @@ export class Style {
|
|
|
318
318
|
anchorsEqual(this.anchor, other.anchor) &&
|
|
319
319
|
this.boxFrame === other.boxFrame &&
|
|
320
320
|
this.bidi === other.bidi &&
|
|
321
|
-
this.
|
|
322
|
-
this.
|
|
321
|
+
this.validity.validUntil === other.validity.validUntil &&
|
|
322
|
+
this.validity.validFrom === other.validity.validFrom);
|
|
323
323
|
}
|
|
324
324
|
/**
|
|
325
|
-
* The
|
|
325
|
+
* The colors this style puts on screen at `colorSystem`: each flattened
|
|
326
326
|
* onto what lies beneath it — the background onto the terminal's black, the
|
|
327
327
|
* foreground onto that background — then downgraded to the depth. The one
|
|
328
328
|
* account of what a style draws: `toSgrCodes` encodes exactly these, and a
|
|
@@ -368,7 +368,7 @@ export class Style {
|
|
|
368
368
|
}
|
|
369
369
|
/**
|
|
370
370
|
* The look as a canonical string that round-trips through `Style.parse()`:
|
|
371
|
-
*
|
|
371
|
+
* colors, attributes and the link, which is all a style string can spell.
|
|
372
372
|
* What a style carries beyond its look — `meta`, `anchor`, `boxFrame`, `bidi`, `hold` —
|
|
373
373
|
* has no spelling and is not here, so two styles that differ only there
|
|
374
374
|
* read alike; `equals` tells them apart.
|
|
@@ -516,7 +516,7 @@ export class Theme {
|
|
|
516
516
|
// --- Parse helpers ---
|
|
517
517
|
const ATTRIBUTE_SET = new Set(ATTRIBUTE_NAMES);
|
|
518
518
|
// The words each position of a definition can hold: a bare token is a keyword,
|
|
519
|
-
// an attribute or a
|
|
519
|
+
// an attribute or a color name; `on` takes a color name; `not` an attribute.
|
|
520
520
|
// The short aliases are left out, since `b` is no help to someone who typed
|
|
521
521
|
// `bolt` and a one-letter name sits one edit from every other short word.
|
|
522
522
|
// [LAW:one-source-of-truth] Derived from the lists the parser accepts from; the
|
|
@@ -548,8 +548,8 @@ function editDistance(a, b) {
|
|
|
548
548
|
* Plausible means within one edit per three letters, at least one, which lets
|
|
549
549
|
* `rd` reach `red` and keeps `hello` from reaching `yellow`. Every name tied
|
|
550
550
|
* for nearest is offered: `gold` is one edit from `bold` and from three
|
|
551
|
-
* `goldN`
|
|
552
|
-
* tell from a finding. Case is not an edit, because the
|
|
551
|
+
* `goldN` colors, and choosing among them would be a guess the reader cannot
|
|
552
|
+
* tell from a finding. Case is not an edit, because the color parser ignores
|
|
553
553
|
* it: `Cyna` is as near `cyan` as `cyna` is.
|
|
554
554
|
*
|
|
555
555
|
* This runs on every render that meets the bad style, since only successful
|
|
@@ -571,12 +571,12 @@ function nearMiss(word, words) {
|
|
|
571
571
|
return names.length === 0 ? "" : ` (did you mean ${names.join(" or ")}?)`;
|
|
572
572
|
}
|
|
573
573
|
/**
|
|
574
|
-
* A style token read as a
|
|
574
|
+
* A style token read as a color. The color parser's own error is the reason
|
|
575
575
|
* the token failed, so it rides along twice: in the message, for a reader with
|
|
576
576
|
* only the text, and as `cause`, for code that wants the original error.
|
|
577
577
|
*
|
|
578
|
-
* [LAW:single-enforcer] Both
|
|
579
|
-
* the near miss is named here rather than by the
|
|
578
|
+
* [LAW:single-enforcer] Both color positions in a definition rewrap here, and
|
|
579
|
+
* the near miss is named here rather than by the color parser: only a
|
|
580
580
|
* definition knows whether the token could also have been an attribute.
|
|
581
581
|
*/
|
|
582
582
|
function parseStyleColor(token, failure, words) {
|
|
@@ -655,7 +655,7 @@ function resolveColor(c) {
|
|
|
655
655
|
// so it is no background: a style added on top of another keeps that one's,
|
|
656
656
|
// which is what Textual's `#00000000` means. A transparent foreground is not
|
|
657
657
|
// the same, it draws its glyph in whatever lies beneath it — the background,
|
|
658
|
-
// or `SURFACE_BLACK` when there is none — so it stays a
|
|
658
|
+
// or `SURFACE_BLACK` when there is none — so it stays a color.
|
|
659
659
|
function resolveBackground(c) {
|
|
660
660
|
const spec = resolveColor(c);
|
|
661
661
|
return spec?.value?.alpha === 0 ? undefined : spec;
|
|
@@ -672,11 +672,11 @@ export const DEFAULT_STYLES = {
|
|
|
672
672
|
italic: false,
|
|
673
673
|
underline: false,
|
|
674
674
|
blink: false,
|
|
675
|
-
|
|
675
|
+
rapidBlink: false,
|
|
676
676
|
reverse: false,
|
|
677
677
|
conceal: false,
|
|
678
678
|
strike: false,
|
|
679
|
-
|
|
679
|
+
doubleUnderline: false,
|
|
680
680
|
frame: false,
|
|
681
681
|
encircle: false,
|
|
682
682
|
overline: false,
|
|
@@ -686,11 +686,11 @@ export const DEFAULT_STYLES = {
|
|
|
686
686
|
italic: new Style({ italic: true }),
|
|
687
687
|
underline: new Style({ underline: true }),
|
|
688
688
|
blink: new Style({ blink: true }),
|
|
689
|
-
|
|
689
|
+
rapidBlink: new Style({ rapidBlink: true }),
|
|
690
690
|
reverse: new Style({ reverse: true }),
|
|
691
691
|
conceal: new Style({ conceal: true }),
|
|
692
692
|
strike: new Style({ strike: true }),
|
|
693
|
-
|
|
693
|
+
doubleUnderline: new Style({ doubleUnderline: true }),
|
|
694
694
|
frame: new Style({ frame: true }),
|
|
695
695
|
encircle: new Style({ encircle: true }),
|
|
696
696
|
overline: new Style({ overline: true }),
|
|
@@ -755,9 +755,9 @@ export const DEFAULT_STYLES = {
|
|
|
755
755
|
"syntax.number": Style.parse("cyan"),
|
|
756
756
|
"syntax.comment": Style.parse("dim italic"),
|
|
757
757
|
"syntax.line_number": Style.parse("dim"),
|
|
758
|
-
// Ink and ground both from the fixed 256-
|
|
758
|
+
// Ink and ground both from the fixed 256-color greys: the terminal theme's
|
|
759
759
|
// own foreground is dark on a light theme and would vanish on grey27. At 16
|
|
760
|
-
//
|
|
760
|
+
// colors `Syntax` draws it without the pair (`groundedStyle`).
|
|
761
761
|
"syntax.line_number.highlight": Style.parse("bold grey93 on grey27"),
|
|
762
762
|
// Markdown
|
|
763
763
|
"markdown.h1": Style.parse("bold underline"),
|
|
@@ -767,7 +767,7 @@ export const DEFAULT_STYLES = {
|
|
|
767
767
|
"markdown.h5": Style.parse("italic"),
|
|
768
768
|
"markdown.h6": Style.parse("dim"),
|
|
769
769
|
// A fixed cyan, not the theme's: `cyan` is dark enough on some themes to
|
|
770
|
-
// sink into grey11. Bold, as Rich's is: at 16
|
|
770
|
+
// sink into grey11. Bold, as Rich's is: at 16 colors a renderable draws it
|
|
771
771
|
// without its pair (`groundedStyle`), and bold is what still marks code.
|
|
772
772
|
"markdown.code": Style.parse("bold dark_turquoise on grey11"),
|
|
773
773
|
"markdown.em": Style.parse("italic"),
|
package/dist/core/text.d.ts
CHANGED
|
@@ -85,8 +85,8 @@ export declare class RichText implements Renderable, Measurable {
|
|
|
85
85
|
* any spans covering the leftmost (side="left") or rightmost (side="right")
|
|
86
86
|
* character.
|
|
87
87
|
*
|
|
88
|
-
* [LAW:locality-or-seam] Used by `
|
|
89
|
-
* adjacent `Strip` items.
|
|
88
|
+
* [LAW:locality-or-seam] Used by `Separator`s to paint the transition between
|
|
89
|
+
* adjacent `Strip` items. Separators only ever need the column adjacent to
|
|
90
90
|
* them, so the cell type exposes that column rather than constraining its
|
|
91
91
|
* interior to be uniform. For RichText with uniform styling, both edges
|
|
92
92
|
* return the same style; for RichText with edge variation, each edge
|
package/dist/core/text.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { cellLen, cellCount, cellFit, cellFitEnd, asCellCol, expandTabs, parseTabSize } from "./cells.js";
|
|
5
5
|
import { closed, closing } from "./bidi.js";
|
|
6
6
|
import { controlClass, dispositionOf, pictureOf } from "./control-codes.js";
|
|
7
|
-
import {
|
|
7
|
+
import { reorder, drawnTail, edges, hangingWhitespace, measured } from "./orient.js";
|
|
8
8
|
import { divideLine, wordWidths } from "./wrap.js";
|
|
9
9
|
import { Segment } from "./segment.js";
|
|
10
10
|
import { Style, NULL_STYLE, StyleSyntaxError } from "./style.js";
|
|
@@ -67,7 +67,7 @@ function sanitizeStyleLink(style) {
|
|
|
67
67
|
* lays its text out anew, so a stamp naming where a cell sat in the output it
|
|
68
68
|
* came from would name the wrong cell once it wraps, slices or overlaps; the
|
|
69
69
|
* owner that renders the RichText is the one that stamps its cells. A
|
|
70
|
-
* hold stays — `
|
|
70
|
+
* hold stays — `validFrom` and `validUntil`: when a span's cells began and
|
|
71
71
|
* next change is true of them wherever the text lays them, so a frame
|
|
72
72
|
* appended into a line still says when it turns.
|
|
73
73
|
*/
|
|
@@ -264,8 +264,8 @@ export class RichText {
|
|
|
264
264
|
* any spans covering the leftmost (side="left") or rightmost (side="right")
|
|
265
265
|
* character.
|
|
266
266
|
*
|
|
267
|
-
* [LAW:locality-or-seam] Used by `
|
|
268
|
-
* adjacent `Strip` items.
|
|
267
|
+
* [LAW:locality-or-seam] Used by `Separator`s to paint the transition between
|
|
268
|
+
* adjacent `Strip` items. Separators only ever need the column adjacent to
|
|
269
269
|
* them, so the cell type exposes that column rather than constraining its
|
|
270
270
|
* interior to be uniform. For RichText with uniform styling, both edges
|
|
271
271
|
* return the same style; for RichText with edge variation, each edge
|
|
@@ -757,7 +757,7 @@ export class RichText {
|
|
|
757
757
|
for (let index = 0; index < logicalLines.length; index += 1) {
|
|
758
758
|
// [LAW:dataflow-not-control-flow] Every line runs the same steps; the
|
|
759
759
|
// order is the value `directed` and `orient` take.
|
|
760
|
-
const { line, oriented, orient } =
|
|
760
|
+
const { line, oriented, orient } = reorder(logicalLines[index], order);
|
|
761
761
|
const free = spanFree[index];
|
|
762
762
|
const terminateLine = index < logicalLines.length - 1;
|
|
763
763
|
// Wrap first, overflow last — the reference's order, and the reason a
|
package/dist/core/timeline.d.ts
CHANGED
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
* one time it holds, so there is no origin for it to be wrong about.
|
|
16
16
|
* [LAW:types-are-the-program]
|
|
17
17
|
*
|
|
18
|
-
* `run` is an animation on host time. Its `
|
|
18
|
+
* `run` is an animation on host time. Its `validUntil` is the host moment
|
|
19
19
|
* the mapped time reaches the animation's own answer, which is what
|
|
20
20
|
* `Spinner`'s speed scaled its holds for before this existed: an answer a
|
|
21
21
|
* host reads is on the host's timeline, and a beat over scaled time answers
|
|
22
22
|
* on the scaled one. Run backwards, the host next sees a change when the
|
|
23
23
|
* mapped time drops under where the value began — the animation's
|
|
24
|
-
* `
|
|
24
|
+
* `validFrom` — so a reversed loop turns exactly at its hold boundaries,
|
|
25
25
|
* and a reversed one-shot changes at its switch and never before its start.
|
|
26
26
|
* Paused, nothing changes: never, and never did. The host moment is the
|
|
27
27
|
* first host float the map carries past the edge, searched out from the sum
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
* hands in, so the same host time maps to the same animation time at one
|
|
51
51
|
* sample a second or sixty.
|
|
52
52
|
*/
|
|
53
|
-
import { Animation, type
|
|
53
|
+
import { Animation, type Behavior } from "./animation.js";
|
|
54
54
|
/**
|
|
55
55
|
* A map from host time to animation time. Playing, it is `time` at `origin`
|
|
56
56
|
* moving `rate` animation seconds a host second; paused, it is `time` at
|
|
@@ -95,7 +95,7 @@ export declare const Timeline: {
|
|
|
95
95
|
* Reduced, it is the animation reduced on the same timeline: what shows
|
|
96
96
|
* still follows the timeline, and only the motion is gone.
|
|
97
97
|
*/
|
|
98
|
-
run<T>(timeline: Timeline, animation:
|
|
98
|
+
run<T>(timeline: Timeline, animation: Behavior<T>): Animation<T>;
|
|
99
99
|
/**
|
|
100
100
|
* Every one of `animations` at once, each on a timeline playing from its
|
|
101
101
|
* index times `delay` seconds after the earliest, their values in order, on
|
|
@@ -105,5 +105,5 @@ export declare const Timeline: {
|
|
|
105
105
|
* Reduced, the offsets are the cascade's choreography, which is motion: every
|
|
106
106
|
* child reduced at once, so from 0 everyone has arrived.
|
|
107
107
|
*/
|
|
108
|
-
stagger<T>(animations: readonly
|
|
108
|
+
stagger<T>(animations: readonly Behavior<T>[], delay: number): Animation<readonly T[]>;
|
|
109
109
|
};
|
package/dist/core/timeline.js
CHANGED
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
* one time it holds, so there is no origin for it to be wrong about.
|
|
16
16
|
* [LAW:types-are-the-program]
|
|
17
17
|
*
|
|
18
|
-
* `run` is an animation on host time. Its `
|
|
18
|
+
* `run` is an animation on host time. Its `validUntil` is the host moment
|
|
19
19
|
* the mapped time reaches the animation's own answer, which is what
|
|
20
20
|
* `Spinner`'s speed scaled its holds for before this existed: an answer a
|
|
21
21
|
* host reads is on the host's timeline, and a beat over scaled time answers
|
|
22
22
|
* on the scaled one. Run backwards, the host next sees a change when the
|
|
23
23
|
* mapped time drops under where the value began — the animation's
|
|
24
|
-
* `
|
|
24
|
+
* `validFrom` — so a reversed loop turns exactly at its hold boundaries,
|
|
25
25
|
* and a reversed one-shot changes at its switch and never before its start.
|
|
26
26
|
* Paused, nothing changes: never, and never did. The host moment is the
|
|
27
27
|
* first host float the map carries past the edge, searched out from the sum
|
|
@@ -82,10 +82,10 @@ function played(animation, { origin, time, rate }) {
|
|
|
82
82
|
// Forwards, the host next sees the animation's own next change, and the
|
|
83
83
|
// value began when the animation says it did; backwards, it next sees a
|
|
84
84
|
// change where the value began, and the value began where the animation
|
|
85
|
-
// says it ends. A hold is `[
|
|
85
|
+
// says it ends. A hold is `[validFrom, validUntil)`, so the far side of
|
|
86
86
|
// an edge is at it going up and strictly under it coming down.
|
|
87
|
-
const ahead = forward ? (t, moves) => animation.
|
|
88
|
-
const behind = forward ? (t, moves) => animation.
|
|
87
|
+
const ahead = forward ? (t, moves) => animation.validUntil(t, moves) : (t, moves) => animation.validFrom(t, moves);
|
|
88
|
+
const behind = forward ? (t, moves) => animation.validFrom(t, moves) : (t, moves) => animation.validUntil(t, moves);
|
|
89
89
|
const past = forward ? (t, edge) => t >= edge : (t, edge) => t < edge;
|
|
90
90
|
// The first host moment the map carries past `edge`, an animation time.
|
|
91
91
|
// An edge at infinity, or one so far off at this rate that no host float
|
|
@@ -97,13 +97,13 @@ function played(animation, { origin, time, rate }) {
|
|
|
97
97
|
};
|
|
98
98
|
return Animation.of({
|
|
99
99
|
at: (host) => animation.at(mapped(hostTime(host))),
|
|
100
|
-
|
|
100
|
+
validUntil(host, moves) {
|
|
101
101
|
const h = hostTime(host);
|
|
102
102
|
const t = mapped(h);
|
|
103
103
|
const edge = ahead(t, moves);
|
|
104
104
|
return edge === t ? h : Math.max(h, hostOf(edge));
|
|
105
105
|
},
|
|
106
|
-
|
|
106
|
+
validFrom(host, moves) {
|
|
107
107
|
const h = hostTime(host);
|
|
108
108
|
const t = mapped(h);
|
|
109
109
|
const edge = behind(t, moves);
|
|
@@ -154,8 +154,8 @@ export const Timeline = {
|
|
|
154
154
|
return played(animation, timeline);
|
|
155
155
|
return Animation.of({
|
|
156
156
|
at: (host) => animation.at(Timeline.at(timeline, host)),
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
validUntil: (host) => (hostTime(host), Number.POSITIVE_INFINITY),
|
|
158
|
+
validFrom: (host) => (hostTime(host), Number.NEGATIVE_INFINITY),
|
|
159
159
|
reduced: () => Timeline.run(timeline, animation.reduced()),
|
|
160
160
|
});
|
|
161
161
|
},
|
package/dist/core/tween.d.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Tween — a value eased from one number to another over seconds, then held:
|
|
3
3
|
* the animation a progress bar's fill, a counter or a width is handed so it
|
|
4
4
|
* moves to its new value instead of jumping. The first `Animation` of a
|
|
5
|
-
* value that is never drawn as cells, so its `
|
|
5
|
+
* value that is never drawn as cells, so its `validUntil` is its only way of
|
|
6
6
|
* saying when to look again (`./animation.ts`).
|
|
7
7
|
*
|
|
8
8
|
* The value at `t` is the `Timing`'s ease of the way from `from` to `to`
|
|
9
|
-
* through `
|
|
9
|
+
* through `WrapMode.once(0, seconds)`: `from` at `t ≤ 0` whenever the ease
|
|
10
10
|
* starts at 0, as every built-in does but `step-start` and the steps that
|
|
11
11
|
* jump at the start of their interval, which show their first jump before
|
|
12
12
|
* the tween begins, as `ColorRamp.at` does; `to` from `seconds` on. It is
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
* tween(old.at(t₁), to, timing))` — and starts from where it is because
|
|
26
26
|
* that is where it was built from. [LAW:no-ambient-temporal-coupling]
|
|
27
27
|
*
|
|
28
|
-
* Over
|
|
29
|
-
* `over`): the ramp is already the one place two
|
|
30
|
-
* OKLCH, and a
|
|
28
|
+
* Over colors it is a `ColorRamp` read over time (`../themes/ramp.ts`,
|
|
29
|
+
* `over`): the ramp is already the one place two colors are blended, in
|
|
30
|
+
* OKLCH, and a color tween is a two-stop ramp over its seconds, not a
|
|
31
31
|
* second blender. [LAW:one-source-of-truth]
|
|
32
32
|
*
|
|
33
33
|
* Tier 6 of `src/core/`: `./easing.ts` and `./animation.ts`, nothing else.
|
|
@@ -41,7 +41,7 @@ import { type Timing } from "./easing.js";
|
|
|
41
41
|
* every ease that starts at 0), `to` after, and so
|
|
42
42
|
* seen at its end, never mid-way, by a host whose frames are further apart
|
|
43
43
|
* than it is long. `from` and `to` must be finite; the seconds are checked
|
|
44
|
-
* where every one-shot's are, in `
|
|
44
|
+
* where every one-shot's are, in `WrapMode.once`. A tween to where it already
|
|
45
45
|
* is is `Animation.constant(from)`, decided here once: the blend would land
|
|
46
46
|
* one ulp off `from` at some `p`, and a value that never moves is one that
|
|
47
47
|
* never changes, so a host is told not to look again. [LAW:parse-dont-validate]
|
package/dist/core/tween.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Tween — a value eased from one number to another over seconds, then held:
|
|
3
3
|
* the animation a progress bar's fill, a counter or a width is handed so it
|
|
4
4
|
* moves to its new value instead of jumping. The first `Animation` of a
|
|
5
|
-
* value that is never drawn as cells, so its `
|
|
5
|
+
* value that is never drawn as cells, so its `validUntil` is its only way of
|
|
6
6
|
* saying when to look again (`./animation.ts`).
|
|
7
7
|
*
|
|
8
8
|
* The value at `t` is the `Timing`'s ease of the way from `from` to `to`
|
|
9
|
-
* through `
|
|
9
|
+
* through `WrapMode.once(0, seconds)`: `from` at `t ≤ 0` whenever the ease
|
|
10
10
|
* starts at 0, as every built-in does but `step-start` and the steps that
|
|
11
11
|
* jump at the start of their interval, which show their first jump before
|
|
12
12
|
* the tween begins, as `ColorRamp.at` does; `to` from `seconds` on. It is
|
|
@@ -25,23 +25,23 @@
|
|
|
25
25
|
* tween(old.at(t₁), to, timing))` — and starts from where it is because
|
|
26
26
|
* that is where it was built from. [LAW:no-ambient-temporal-coupling]
|
|
27
27
|
*
|
|
28
|
-
* Over
|
|
29
|
-
* `over`): the ramp is already the one place two
|
|
30
|
-
* OKLCH, and a
|
|
28
|
+
* Over colors it is a `ColorRamp` read over time (`../themes/ramp.ts`,
|
|
29
|
+
* `over`): the ramp is already the one place two colors are blended, in
|
|
30
|
+
* OKLCH, and a color tween is a two-stop ramp over its seconds, not a
|
|
31
31
|
* second blender. [LAW:one-source-of-truth]
|
|
32
32
|
*
|
|
33
33
|
* Tier 6 of `src/core/`: `./easing.ts` and `./animation.ts`, nothing else.
|
|
34
34
|
* [LAW:one-way-deps]
|
|
35
35
|
*/
|
|
36
36
|
import { Animation } from "./animation.js";
|
|
37
|
-
import {
|
|
37
|
+
import { WrapMode } from "./easing.js";
|
|
38
38
|
/**
|
|
39
39
|
* `from` eased to `to` over `timing`, as an `Animation<number>`: moving from
|
|
40
40
|
* 0 to `timing.seconds` on its own clock, the ease of 0 before (`from`, for
|
|
41
41
|
* every ease that starts at 0), `to` after, and so
|
|
42
42
|
* seen at its end, never mid-way, by a host whose frames are further apart
|
|
43
43
|
* than it is long. `from` and `to` must be finite; the seconds are checked
|
|
44
|
-
* where every one-shot's are, in `
|
|
44
|
+
* where every one-shot's are, in `WrapMode.once`. A tween to where it already
|
|
45
45
|
* is is `Animation.constant(from)`, decided here once: the blend would land
|
|
46
46
|
* one ulp off `from` at some `p`, and a value that never moves is one that
|
|
47
47
|
* never changes, so a host is told not to look again. [LAW:parse-dont-validate]
|
|
@@ -52,7 +52,7 @@ export function tween(from, to, timing) {
|
|
|
52
52
|
throw new RangeError(`tween ${name} must be finite, got ${v}`);
|
|
53
53
|
}
|
|
54
54
|
const { ease, seconds } = timing;
|
|
55
|
-
const phase =
|
|
55
|
+
const phase = WrapMode.once(0, seconds);
|
|
56
56
|
if (from === to)
|
|
57
57
|
return Animation.constant(from);
|
|
58
58
|
return Animation.of({
|
|
@@ -63,8 +63,8 @@ export function tween(from, to, timing) {
|
|
|
63
63
|
// Before it begins the value is held until 0; while it moves, every
|
|
64
64
|
// frame; from `seconds` on, never again — and it became what it is at
|
|
65
65
|
// `seconds`, or always was before it began.
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
validUntil: (t) => (t < 0 ? 0 : t < seconds ? t : Number.POSITIVE_INFINITY),
|
|
67
|
+
validFrom: (t) => (t < 0 ? Number.NEGATIVE_INFINITY : t < seconds ? t : seconds),
|
|
68
68
|
// A one-shot, reduced, cuts from where it starts to where it arrives.
|
|
69
69
|
reduced: () => Animation.cut(from, to),
|
|
70
70
|
});
|
package/dist/core/view.d.ts
CHANGED
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
* anything it draws. What the drawn frame says about when it changes is on
|
|
23
23
|
* the timeline's clock, and `drawView` carries it back onto the host's by
|
|
24
24
|
* running the frame through the same timeline: the frame is a sample held
|
|
25
|
-
* for the intersection of its cells' holds (`Segment.
|
|
26
|
-
* `Segment.
|
|
27
|
-
* (`RenderOptions.
|
|
25
|
+
* for the intersection of its cells' holds (`Segment.validFrom`,
|
|
26
|
+
* `Segment.validUntil`) and the holds it was told that no cell carries
|
|
27
|
+
* (`RenderOptions.onValidity`), and `Timeline.run` is the one place a hold is
|
|
28
28
|
* mapped onto host time, forwards, backwards or paused.
|
|
29
29
|
*
|
|
30
30
|
* What a host does with that is its own policy, and it reads it off the
|
|
@@ -86,7 +86,7 @@ export interface FrameSays {
|
|
|
86
86
|
/** The host time the frame was drawn at. */
|
|
87
87
|
readonly t: number;
|
|
88
88
|
/** The first host moment, never before `t`, at which the frame may stop showing this: `t` while it moves, `Infinity` once it never will. */
|
|
89
|
-
readonly
|
|
89
|
+
readonly validUntil: number;
|
|
90
90
|
}
|
|
91
91
|
/** A frame drawn from a view: its lines, and what it says. */
|
|
92
92
|
export interface DrawnView extends FrameSays {
|
package/dist/core/view.js
CHANGED
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
* anything it draws. What the drawn frame says about when it changes is on
|
|
23
23
|
* the timeline's clock, and `drawView` carries it back onto the host's by
|
|
24
24
|
* running the frame through the same timeline: the frame is a sample held
|
|
25
|
-
* for the intersection of its cells' holds (`Segment.
|
|
26
|
-
* `Segment.
|
|
27
|
-
* (`RenderOptions.
|
|
25
|
+
* for the intersection of its cells' holds (`Segment.validFrom`,
|
|
26
|
+
* `Segment.validUntil`) and the holds it was told that no cell carries
|
|
27
|
+
* (`RenderOptions.onValidity`), and `Timeline.run` is the one place a hold is
|
|
28
28
|
* mapped onto host time, forwards, backwards or paused.
|
|
29
29
|
*
|
|
30
30
|
* What a host does with that is its own policy, and it reads it off the
|
|
@@ -78,9 +78,9 @@ export function frameNow(host, time) {
|
|
|
78
78
|
return { time: frameTime(time), host };
|
|
79
79
|
}
|
|
80
80
|
/** What a frame not yet drawn at host time `t` says: nothing. */
|
|
81
|
-
export const undrawn = (t) => ({ t,
|
|
81
|
+
export const undrawn = (t) => ({ t, validUntil: Number.POSITIVE_INFINITY });
|
|
82
82
|
/** The hold of the frame `lines` draw, told `told` besides: the intersection of its cells' holds and it. */
|
|
83
|
-
const
|
|
83
|
+
const frameValidity = (lines, told) => lines.reduce((validity, row) => intersection(validity, { validFrom: Segment.validFrom(row), validUntil: Segment.validUntil(row) }), told);
|
|
84
84
|
/**
|
|
85
85
|
* `view` drawn by `drawnBy` at `time` under `options`, its lines shaped by
|
|
86
86
|
* `draw` — the host's own render under those options, with its height and
|
|
@@ -93,16 +93,16 @@ const frameHold = (lines, told) => lines.reduce((hold, row) => intersection(hold
|
|
|
93
93
|
export function drawView(view, time, drawnBy, options, draw) {
|
|
94
94
|
const { now: host, timeline } = time;
|
|
95
95
|
let told = NEVER_CHANGES;
|
|
96
|
-
const
|
|
97
|
-
told = intersection(told,
|
|
96
|
+
const onValidity = (validity) => {
|
|
97
|
+
told = intersection(told, validity);
|
|
98
98
|
};
|
|
99
99
|
// Made before the render opens: the one time the frame has.
|
|
100
100
|
const frame = frameNow(drawnBy, time);
|
|
101
|
-
const lines = draw(view, { ...options, frame,
|
|
102
|
-
const
|
|
101
|
+
const lines = draw(view, { ...options, frame, onValidity });
|
|
102
|
+
const validity = frameValidity(lines, told);
|
|
103
103
|
// The frame as the sample of the view it is, on the timeline's clock; the
|
|
104
104
|
// timeline says when the host's clock leaves its hold.
|
|
105
|
-
const sample = { at: () => lines,
|
|
106
|
-
const
|
|
107
|
-
return { t: host, lines,
|
|
105
|
+
const sample = { at: () => lines, validUntil: () => validity.validUntil, validFrom: () => validity.validFrom, reduced: () => sample };
|
|
106
|
+
const validUntil = Timeline.run(timeline, sample).validUntil(host);
|
|
107
|
+
return { t: host, lines, validUntil };
|
|
108
108
|
}
|