@ng-native/fabric 0.2.0 → 0.4.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/engine.d.ts CHANGED
@@ -7,8 +7,8 @@
7
7
  * because a persistent parent holds references to specific child handles. That bubble is
8
8
  * inherent and is what React's own Fabric renderer does.
9
9
  */
10
- import { type Conditions, type StyleCache, type StyleSheet, type TokenValue } from './css.ts';
11
- import { type AnimationSpec, type RunningAnimation, type Transition } from './transition.ts';
10
+ import { type Conditions, type DeferredDeclaration, type StyleCache, type StyleSheet, type TokenValue } from './css.ts';
11
+ import { type AnimationSpec, type Keyframe, type RunningAnimation, type Transition } from './transition.ts';
12
12
  import { type DrivenProperty, type EventFeed, type NativeAnimated, type ScrollAxis, type ScrollDrive, type ScrollRange, type StaticTransform } from './native-drive.ts';
13
13
  import type { DrivenChannels } from './scroll-animation.ts';
14
14
  export type FabricNode = {
@@ -19,12 +19,16 @@ import type { HostEngine, HostNode, Settling } from './host.ts';
19
19
  /** A node's scroll-driven animation: what it plays, what drives it, and the frame it commits. */
20
20
  interface ScrollAnimation {
21
21
  readonly spec: AnimationSpec;
22
+ /** The `@keyframes` it was laid out from, so a hot swap that edits them lays it out again. */
23
+ readonly frames: readonly Keyframe[];
22
24
  readonly tracks: ReadonlyMap<string, readonly {
23
25
  offset: number;
24
26
  value: unknown;
25
27
  }[]>;
26
28
  readonly resting: Record<string, unknown>;
27
29
  readonly first: Record<string, unknown>;
30
+ /** The colour the node inherits, which the tracks were built with, for frames that read it. */
31
+ readonly inherited: unknown;
28
32
  readonly source: EngineNode | null;
29
33
  readonly drive: {
30
34
  update(channels: DrivenChannels): void;
@@ -65,6 +69,17 @@ export interface FabricUIManager {
65
69
  */
66
70
  measureInWindow?(node: FabricNode, onSuccess: (x: number, y: number, width: number, height: number) => void): void;
67
71
  }
72
+ /**
73
+ * RN's `directEventTypes`: delivered to the target only, never up the tree. Everything else
74
+ * bubbles, which matches RN's `bubblingEventTypes` for the touch and input events that matter.
75
+ * The web host's engine reads this set too, so both hosts deliver an event the same way.
76
+ *
77
+ * ponytail: a hand-kept set rather than real ViewConfigs. It is wrong only for a nested
78
+ * scroll view, where an ancestor listening for the same direct event would not fire (correct)
79
+ * but a third-party component's custom direct event would bubble (harmless in practice).
80
+ * Swap it for per-component ViewConfig metadata if that ever matters.
81
+ */
82
+ export declare const DIRECT_EVENTS: ReadonlySet<string>;
68
83
  /**
69
84
  * What a listener receives. RN's synthetic event carries more, but `nativeEvent` is the part
70
85
  * every RN API is documented against, and `stopPropagation` is the part a nested control needs.
@@ -77,6 +92,11 @@ export interface FabricUIManager {
77
92
  */
78
93
  export interface NativeSyntheticEvent<T = unknown> {
79
94
  readonly nativeEvent: T;
95
+ /**
96
+ * The node the event happened on, which a listener further up can compare with its own: RN's
97
+ * `event.target`. Null where a host has no node to name.
98
+ */
99
+ readonly target?: unknown;
80
100
  stopPropagation(): void;
81
101
  isPropagationStopped(): boolean;
82
102
  }
@@ -87,8 +107,9 @@ export interface NativeSyntheticEvent<T = unknown> {
87
107
  */
88
108
  export declare class SyntheticEvent<T = unknown> implements NativeSyntheticEvent<T> {
89
109
  readonly nativeEvent: T;
110
+ readonly target: unknown;
90
111
  private stopped;
91
- constructor(nativeEvent: T);
112
+ constructor(nativeEvent: T, target?: unknown);
92
113
  stopPropagation(): void;
93
114
  isPropagationStopped(): boolean;
94
115
  }
@@ -147,6 +168,8 @@ interface Committed {
147
168
  props: Record<string, unknown>;
148
169
  /** The child handles this node was committed with, in order. */
149
170
  childHandles: FabricNode[];
171
+ /** The native view it was created as, which a clone cannot change. */
172
+ viewName: string;
150
173
  }
151
174
  export interface EngineNode extends HostNode {
152
175
  readonly kind: NodeKind;
@@ -171,6 +194,27 @@ export interface EngineNode extends HostNode {
171
194
  styleCache: StyleCache | null;
172
195
  /** Set when something that could change what this node matches has changed. */
173
196
  styleDirty: boolean;
197
+ /** A family left out while it loads. See `loadingFamilies`. */
198
+ heldFamily?: string;
199
+ /** See `StyleTarget.inlineInherits`. */
200
+ inlineInherits?: boolean;
201
+ /** See `StyleTarget.boundStyle`: the declarations, and the same by the property each sets. */
202
+ boundStyle?: readonly DeferredDeclaration[] | null;
203
+ boundByProp?: Map<string, DeferredDeclaration>;
204
+ /**
205
+ * Whether this node, or one inside it, takes touches under a `pointer-events: none` it would
206
+ * otherwise inherit. Kept as each node is reconciled, children first. See `noteTouches`.
207
+ */
208
+ touchWithin?: boolean;
209
+ /**
210
+ * The paragraph the engine makes around a run of text written straight into a view. It is in no
211
+ * template and in no node's `children`: it holds the text, and commits where the text would.
212
+ */
213
+ box?: EngineNode;
214
+ /** A node the engine made, which no rule matches: it only inherits. */
215
+ anonymous?: true;
216
+ /** See `StyleTarget.styled`. */
217
+ styled?: true;
174
218
  /** `:focus`, from the native focus and blur events. */
175
219
  focused?: boolean;
176
220
  /** `:active`, set on the responder and every ancestor of it. */
@@ -203,6 +247,13 @@ export interface EngineNode extends HostNode {
203
247
  parts: readonly unknown[];
204
248
  value: unknown[];
205
249
  };
250
+ /** The commit that created this node's view, by its number: see `Engine.commitUnseen`. */
251
+ bornIn?: number;
252
+ /** The last bound `transform` string and the list it reads as, undefined where CSS cannot. */
253
+ boundTransform?: {
254
+ text: string;
255
+ list: unknown[] | undefined;
256
+ };
206
257
  /**
207
258
  * Set by the component that owns this element. A host primitive that reaches a commit without it
208
259
  * was written in a template that never imported the component, which is reported in dev.
@@ -214,6 +265,14 @@ export interface EngineNode extends HostNode {
214
265
  * knows. See `markComponentHost`.
215
266
  */
216
267
  componentHost?: true;
268
+ /** See `keepNativeView`. */
269
+ nativeView?: true;
270
+ /**
271
+ * Style weaker than every sheet, where no rule and no inline style says otherwise. What lets the
272
+ * root component's host fill the surface by default and still give way to its own `:host`. See
273
+ * `setDefaultStyle`.
274
+ */
275
+ defaultStyle?: Readonly<Record<string, unknown>>;
217
276
  /**
218
277
  * Hoisted nodes (`registerHoist`) inside this subtree while it is out of the tree, held here
219
278
  * rather than by the engine. See `Engine.releaseDetached`.
@@ -256,6 +315,12 @@ export declare function claimHost(node: HostNode): void;
256
315
  * with the host element in hand, whatever the component's selector.
257
316
  */
258
317
  export declare function markComponentHost(node: HostNode): void;
318
+ /**
319
+ * Say that a component's host is the native view its element name is registered as: a typed
320
+ * wrapper for the view, where a component of the app's own with the same selector is a plain view.
321
+ * Called from the component's constructor. See `ViewNameOptions.yieldsToComponents`.
322
+ */
323
+ export declare function keepNativeView(node: HostNode): void;
259
324
  /** Names Android registers differently. */
260
325
  export declare const ANDROID_VIEW_NAMES: Record<string, string>;
261
326
  export declare function nativePlatform(): string;
@@ -274,7 +339,23 @@ export declare function registerPlatformComponents(platform: string): void;
274
339
  * and skipping it is not cosmetic: `RNSScreenStackHeaderConfig` without its `position: absolute`
275
340
  * joins the screen's flex layout and pushes every page down by the height of the header.
276
341
  */
277
- export declare function registerViewName(elementName: string, viewName: string | PlatformViewName, defaultProps?: Record<string, unknown>): void;
342
+ export declare function registerViewName(elementName: string, viewName: string | PlatformViewName, defaultProps?: Record<string, unknown>, options?: ViewNameOptions): void;
343
+ /** What else a registered view needs the engine to know about it. */
344
+ export interface ViewNameOptions {
345
+ /**
346
+ * The prop the view reads its text from, where it takes no children: SwiftUI's `Text` through
347
+ * `@expo/ui` reads `text`. The text written inside the element becomes that prop, as `<text>`
348
+ * takes its own content, and is not committed as children. An explicit prop wins over it.
349
+ */
350
+ readonly textContent?: string;
351
+ /**
352
+ * Whether the name gives way to a component of the app's own with the same selector, whose host
353
+ * is then a plain view. For a set of views registered under a prefix an app may also use for
354
+ * its design system, as `@expo/ui`'s are under `ui-`. A component that is the view itself, a
355
+ * typed wrapper for it, says so with `keepNativeView`.
356
+ */
357
+ readonly yieldsToComponents?: boolean;
358
+ }
278
359
  /**
279
360
  * A view whose native name differs by platform. Chosen when the view is looked up rather than when
280
361
  * it is registered, so it does not matter which ran first: an app's imports register the router's
@@ -292,6 +373,16 @@ export declare function onFontsRegistered(listener: (families: ReadonlySet<strin
292
373
  * `Engine.fontsRegistered`.
293
374
  */
294
375
  export declare function fontsRegistered(families: Iterable<string>): void;
376
+ /** Faces a load is about to ask the platform for. See `loadingFamilies`. */
377
+ export declare function fontsLoading(families: Iterable<string>): void;
378
+ /** Hear about loads settling, until the returned function is called. */
379
+ export declare function onFontsSettled(listener: (families: ReadonlySet<string>) => void): () => void;
380
+ /**
381
+ * Faces a load asked for and has finished with, registered or not, before `fontsRegistered`.
382
+ * Text held back for one that no load still asks for is laid out with the name again: see
383
+ * `Engine.fontsSettled`.
384
+ */
385
+ export declare function fontsSettled(families: Iterable<string>): void;
295
386
  /**
296
387
  * Commit every `elementName` as a direct child of its nearest `ancestorName`, wherever the
297
388
  * template put it, e.g. `registerHoist('native-header', 'screen')`.
@@ -329,9 +420,12 @@ interface KeptHoist {
329
420
  export interface ViewNameNode {
330
421
  readonly kind: string;
331
422
  readonly name: string;
332
- readonly parent: {
333
- readonly name: string;
334
- } | null;
423
+ readonly parent: ViewNameNode | null;
424
+ /** Whether a component is mounted on it, and whether that component is the native view. */
425
+ readonly componentHost?: boolean;
426
+ readonly nativeView?: boolean;
427
+ /** What it holds, which decides whether one of HTML's text elements is text or a view. */
428
+ readonly children?: readonly ViewNameNode[];
335
429
  }
336
430
  /**
337
431
  * The native view a node commits as: `Paragraph` for a `<text>`, `VirtualText` for one nested in
@@ -416,7 +510,7 @@ export interface EngineStats {
416
510
  firstCommitMs: number;
417
511
  /** Worst commit *after* the mount. This is the number that matters for frame rate. */
418
512
  worstCommitMs: number;
419
- /** Commits that blew a 60fps frame budget, excluding the mount. */
513
+ /** Commits that took longer than 8ms, a frame at 120Hz, excluding the mount. */
420
514
  slowCommits: number;
421
515
  /**
422
516
  * Worst `begin()`..`end()` span, excluding the mount. This brackets Angular's whole render
@@ -452,15 +546,19 @@ export declare class Engine implements HostEngine {
452
546
  * for them. Only those in the tree: see `releaseDetached`.
453
547
  */
454
548
  private readonly hoisted;
455
- /** Whether a child list has lost a member since the last commit. See `releaseDetached`. */
456
- private removedSinceCommit;
549
+ /** The nodes taken out of a child list since the last commit. See `releaseDetached`. */
550
+ private readonly removedSinceCommit;
457
551
  /**
458
- * `@keyframes` by name, across every sheet seen so far. One registry rather than one per sheet,
552
+ * `@keyframes` by name, across every sheet registered. One registry rather than one per sheet,
459
553
  * because that is the scope CSS gives them: a name defined in a global stylesheet is usable
460
554
  * from a component's. The cost is that two components defining the same name collide, last one
461
555
  * in wins, exactly as two stylesheets in a document would.
462
556
  */
463
557
  private readonly keyframes;
558
+ /** Every sheet registered, in the order a document would hold them. See `sheetReplaced`. */
559
+ private readonly sheetOrder;
560
+ /** The `@keyframes` each playing animation was started from. See `startPlaying`. */
561
+ private readonly playedFrames;
464
562
  /** Element names already reported as unclaimed, so a list of a thousand rows reports once. */
465
563
  private readonly reported;
466
564
  private readonly processColor;
@@ -499,6 +597,18 @@ export declare class Engine implements HostEngine {
499
597
  * a caller owns the properties it names and nothing else. Each owner writes all of its own at
500
598
  * once - four insets together, never one - so nothing is left over from a previous rotation.
501
599
  */
600
+ /**
601
+ * Match `sheet` against every node from now on, after the global sheet the engine was made
602
+ * with, and restyle everything; false, and nothing done, when it already is. How a platform
603
+ * applies a component whose CSS is not scoped, such as Angular's `ViewEncapsulation.None`.
604
+ * `replacing` is a sheet added before that this one takes the place of, after a hot swap.
605
+ */
606
+ addGlobalSheet(sheet: StyleSheet, replacing?: StyleSheet): boolean;
607
+ /**
608
+ * Stop matching a sheet `addGlobalSheet` added, and restyle everything; false, and nothing
609
+ * done, when it is not one. A hot swap that leaves a None component no rules, or makes it scoped.
610
+ */
611
+ removeGlobalSheet(sheet: StyleSheet): boolean;
502
612
  updateTokens(next: Readonly<Record<string, TokenValue>>): void;
503
613
  /**
504
614
  * The system text size changed: measure every text and text input again, and commit.
@@ -533,6 +643,11 @@ export declare class Engine implements HostEngine {
533
643
  * text attributes change, which the same cap does. Android sets it only when `fontFamily` is in
534
644
  * the props it is sent, and the engine sends only what changed, so it is sent again once.
535
645
  */
646
+ /**
647
+ * Loads have settled for these families: every node held back for one, a span inside a
648
+ * paragraph included, is laid out with the name again, registered or not. See `loadingFamilies`.
649
+ */
650
+ fontsSettled(families: ReadonlySet<string>): void;
536
651
  fontsRegistered(families: ReadonlySet<string>): void;
537
652
  /**
538
653
  * Put the cursor in a text input; bring anything else on screen, in the scroll view it is in.
@@ -563,16 +678,40 @@ export declare class Engine implements HostEngine {
563
678
  * the wrong height until something else changed.
564
679
  */
565
680
  remeasure(node: EngineNode): void;
681
+ /**
682
+ * A node's component rules are its creating sheet's, so this matches it against `like`'s, or
683
+ * against the one it was created with once `like` is null.
684
+ */
685
+ adoptScope(node: EngineNode, like: EngineNode | null): void;
686
+ /** The sheet each node given another's scope was created with. */
687
+ private readonly ownSheets;
566
688
  /** The window's size, from the conditions media queries use. Zero until the platform says. */
567
689
  get viewport(): {
568
690
  readonly width: number;
569
691
  readonly height: number;
570
692
  };
571
693
  private viewportSize;
694
+ /** The system text size, from the conditions. See `Conditions.fontScale`. */
695
+ private fontScale;
696
+ private readonly viewportWatchers;
697
+ /** Calls `listener` after each change of conditions, which is when `viewport` can change. */
698
+ watchViewport(listener: () => void): () => void;
572
699
  updateConditions(next: Conditions): void;
573
700
  createElement(name: string, sheet?: StyleSheet | null): EngineNode;
574
701
  addClass(node: EngineNode, name: string): void;
575
702
  removeClass(node: EngineNode, name: string): void;
703
+ /**
704
+ * The sheet of the component `node` hosts, whose `:host` rules it matches. Set again when a hot
705
+ * swap replaces the component's sheet, which recreates the views inside but not the host, so the
706
+ * host is styled afresh here.
707
+ */
708
+ setHostSheet(node: EngineNode, sheet: StyleSheet | null): void;
709
+ /**
710
+ * Style for `node` that any matched rule or inline style overrides, as a browser's own default
711
+ * for an element is. `mount` gives the root component's host the surface's height this way, as
712
+ * the web's mount point has, unless the app's `:host` sizes it otherwise.
713
+ */
714
+ setDefaultStyle(node: EngineNode, style: Readonly<Record<string, unknown>> | undefined): void;
576
715
  /** `class="a b"` from a template. Replaces the set rather than adding to it. */
577
716
  setClasses(node: EngineNode, value: string): void;
578
717
  /** Angular's `@if`/`@for`/`ViewContainerRef` markers. Ordered, never committed. */
@@ -581,6 +720,11 @@ export declare class Engine implements HostEngine {
581
720
  appendChild(parent: EngineNode, child: EngineNode): void;
582
721
  insertBefore(parent: EngineNode, child: EngineNode, ref: EngineNode | null): void;
583
722
  removeChild(parent: EngineNode | null, child: EngineNode): void;
723
+ /**
724
+ * A child came or went under a view that takes its text as a prop: that prop changed. A span
725
+ * changes it too, by keeping or dropping the space before it.
726
+ */
727
+ private markTextContent;
584
728
  /** A subtree that went out of the tree is back in: its hoisted nodes commit again. */
585
729
  private wakeHoists;
586
730
  /**
@@ -598,11 +742,18 @@ export declare class Engine implements HostEngine {
598
742
  * whole. So a hoisted node moves to the root of the subtree it left with, which is garbage along
599
743
  * with it if the subtree never returns, and is handed back when it does. An animation on a node
600
744
  * out of the tree stops rather than running a frame loop for something nobody can see, and
601
- * starts again if the node returns.
745
+ * starts again if the node returns. And a node out of the tree when the commit runs forgets its
746
+ * committed views, as a withheld modal does: the commit unmounts them, Fabric never re-enables an
747
+ * unmounted view's events (`EventEmitter::setEnabled`), and committed again they would ignore
748
+ * every touch. It comes back created afresh, as React creates an element it mounts again. One
749
+ * put back before the commit never left, and keeps its views.
602
750
  *
603
- * Once per commit, and only after a removal: the walks are the depth of a handful of nodes.
751
+ * Once per commit, and only after a removal: the walks are the depth of a handful of nodes, and
752
+ * forgetting walks each subtree that left once.
604
753
  */
605
754
  private releaseDetached;
755
+ /** Forget the committed views of each node removed since the last commit that is still out. */
756
+ private forgetDetached;
606
757
  /** The root of the tree a node is in: the engine's root while it is attached. */
607
758
  private topOf;
608
759
  /**
@@ -614,6 +765,11 @@ export declare class Engine implements HostEngine {
614
765
  parentNode(node: EngineNode): EngineNode | null;
615
766
  nextSibling(node: EngineNode): EngineNode | null;
616
767
  setProp(node: EngineNode, key: string, value: unknown): void;
768
+ /**
769
+ * Whether a node's inline style can change what it or anything below it resolves to: it sets,
770
+ * or until now set, a property its children inherit.
771
+ */
772
+ private inlineReachesStyle;
617
773
  /** Whether a node's inline style sets `direction`, remembering that one has. */
618
774
  private noteInlineDirection;
619
775
  /**
@@ -625,6 +781,12 @@ export declare class Engine implements HostEngine {
625
781
  * has changed for the props diff to notice.
626
782
  */
627
783
  styleChanged(node: EngineNode): void;
784
+ /**
785
+ * A bound declaration, `[style.color]`, whose value may be a `var()`. One that is, is kept as a
786
+ * declaration the cascade settles with the node's tokens, as a rule's is, and true is answered:
787
+ * the text is no value to put in the node's style. Any other value forgets what was kept.
788
+ */
789
+ setBoundStyle(node: EngineNode, prop: string, value: unknown): boolean;
628
790
  /**
629
791
  * Set a custom property on a node, `--tint` from `[style.--tint]`, or remove it with `null`.
630
792
  *
@@ -637,6 +799,7 @@ export declare class Engine implements HostEngine {
637
799
  setEventListener(node: EngineNode, topLevelType: string, fn: (event: unknown) => void): () => void;
638
800
  private markProps;
639
801
  private markLaterSiblings;
802
+ /** `node`'s child list changed: `moved` came into it or went out of it. */
640
803
  private markStructure;
641
804
  /** Walk up until we hit a node already known to have a dirty subtree. */
642
805
  private markPath;
@@ -648,6 +811,28 @@ export declare class Engine implements HostEngine {
648
811
  * optimisation.
649
812
  */
650
813
  commit(): boolean;
814
+ /** The first commit whose new views have not been drawn yet, while `commitUnseen` runs. */
815
+ private unseen;
816
+ /**
817
+ * A commit for what changed in the same turn as earlier commits, before a frame was drawn.
818
+ * `since` is how many commits there had been before the first of them (`stats.commits`).
819
+ *
820
+ * A view those commits created has not been seen in the style they gave it, so what this one
821
+ * gives it is where it starts, and no transition runs toward it. That is what a browser
822
+ * does with a class added to an element in the turn that inserted it, and what `animate.enter`
823
+ * is built on: Angular adds the enter class after the render pass that created the element, and
824
+ * takes it off a frame later, which is the one change the transition is for.
825
+ */
826
+ commitUnseen(since: number): boolean;
827
+ /** Nodes that asked for `@keyframes` this commit had not met, by the name they asked for. */
828
+ private readonly awaitingKeyframes;
829
+ /**
830
+ * A sheet is registered when the first node it styles is committed, so a node committed before
831
+ * it can name keyframes that arrive later in the same commit. Those nodes play them from another
832
+ * commit straight away, as a browser applies keyframes however the sheets arrived; a name still
833
+ * unknown once the commit is over is reported.
834
+ */
835
+ private settleKeyframes;
651
836
  private readonly scrollDriver;
652
837
  /** Whether native can move a view by a scroll with no JavaScript in between. */
653
838
  get drivesScroll(): boolean;
@@ -682,9 +867,9 @@ export declare class Engine implements HostEngine {
682
867
  /** Anchors take part in sibling ordering but never reach Fabric. */
683
868
  private visibleChildren;
684
869
  /**
685
- * Everything a node renders with, unprocessed. Precedence, weakest first: native defaults,
686
- * matched CSS, explicit props, inline style, a component's `styleOverride`. Inline wins over CSS for the same reason it does
687
- * on the web.
870
+ * Everything a node renders with, unprocessed. Precedence, weakest first: native defaults, the
871
+ * node's `defaultStyle`, matched CSS, explicit props, inline style, a component's
872
+ * `styleOverride`. Inline wins over CSS for the same reason it does on the web.
688
873
  *
689
874
  * Raw, because this is what the next commit diffs against. Colours and asset ids are converted
690
875
  * on the way out instead (`processed`), and only for the keys that changed: the converters
@@ -724,6 +909,23 @@ export declare class Engine implements HostEngine {
724
909
  * sheets are few.
725
910
  */
726
911
  private registerSheet;
912
+ /**
913
+ * A hot swap edited a component's sheet into `next`, or took it away with null: `sheet`'s
914
+ * `@keyframes` go, and `next`'s take its place among the others, as an edited stylesheet keeps
915
+ * its place in a document. A name another sheet also defines falls back to that one. Every
916
+ * animation re-resolves the name it plays, so one whose keyframes went stops, as in a browser.
917
+ * A `sheet` already gone, such as a global sheet removed, leaves `next` registered last.
918
+ */
919
+ sheetReplaced(sheet: StyleSheet, next: StyleSheet | null): void;
920
+ /**
921
+ * Every sheet's `@font-face` rules again, in order, and every text that names a family matched
922
+ * again: a face whose rule went is no longer matched, though the platform keeps it registered.
923
+ */
924
+ private reindexFonts;
925
+ /** Every sheet's `@keyframes` again, in order, and every animation told to look them up. */
926
+ private reindexKeyframes;
927
+ /** Mark every node under `node` with an animation, so it looks its keyframes up again. */
928
+ private markAnimated;
727
929
  /** Every `@font-face` seen, global as on the web: a face declared in one sheet serves all. */
728
930
  private readonly fontFaces;
729
931
  /** Whether a sheet first used in this commit declared a face. See `rematchFonts`. */
@@ -734,6 +936,8 @@ export declare class Engine implements HostEngine {
734
936
  * Once per sheet that declares faces, so walking the tree costs nothing that matters.
735
937
  */
736
938
  private rematchFonts;
939
+ /** Mark every element under `node` committed with a family, so it is matched again. */
940
+ private markFontText;
737
941
  private readonly knownSheets;
738
942
  /**
739
943
  * Start, advance or stop the `@keyframes` animation a node's style asks for.
@@ -742,8 +946,29 @@ export declare class Engine implements HostEngine {
742
946
  * own frames, which is what lets an element animate in without differing from anything.
743
947
  */
744
948
  private animated;
949
+ /**
950
+ * A clock animation the scroll plays instead: the same animation where only the timeline moved,
951
+ * and one cancelled where the name changed.
952
+ */
953
+ private handOverToScroll;
954
+ /**
955
+ * `animationcancel` for an animation stopped before it ended: the element no longer asks for it,
956
+ * asks for another by name, or its keyframes went, as a browser fires it.
957
+ */
958
+ private cancelPlaying;
745
959
  /** Start the clock on an animation, unless the node is already playing this one. */
746
960
  private startPlaying;
961
+ /**
962
+ * The colour `node` inherits, for frames that set `color: currentColor`, which is that colour
963
+ * wherever the animation has got to, as in CSS. Undefined for frames that do not.
964
+ */
965
+ private inheritedColour;
966
+ /**
967
+ * The name an animation plays now has other frames: a hot swap edited them, or took away the
968
+ * sheet whose copy won. Or the colour its `color: currentColor` stands for has changed. It
969
+ * carries on along the new tracks, on its own clock, as a browser does, paused or not.
970
+ */
971
+ private reframe;
747
972
  /**
748
973
  * `animation-play-state` changed on an animation already playing: pausing holds the frame it
749
974
  * has reached, and running again carries on from there, the paused time left out of its clock.
@@ -763,6 +988,13 @@ export declare class Engine implements HostEngine {
763
988
  * changed on a later commit would reset what native is animating.
764
989
  */
765
990
  private scrollAnimated;
991
+ /**
992
+ * The first frame of a scroll-driven animation already playing. When the colour its
993
+ * `color: currentColor` stands for has changed, that frame's colour is taken from tracks built
994
+ * again. Native drives opacity and transforms only, so a colour holds its first frame, and
995
+ * nothing native animates is touched.
996
+ */
997
+ private rescrolled;
766
998
  /** Hand a scroll-driven animation's channels to native, fed by `source`'s scroll events. */
767
999
  private driveScrolled;
768
1000
  /** The scroll view a scroll-driven animation on `node` follows: the nearest one it is inside. */
@@ -840,6 +1072,22 @@ export declare class Engine implements HostEngine {
840
1072
  * which, per child, was most of what a one-row update cost.
841
1073
  */
842
1074
  private reconcileChildren;
1075
+ /**
1076
+ * The paragraph a run of text written straight into a view is drawn in, or nothing for a run of
1077
+ * whitespace, which a browser draws nothing for between the items of a flex box either.
1078
+ *
1079
+ * It is the text's own, kept on the text node, and no part of the tree: its parent is the view,
1080
+ * so it inherits what the view's text would, and no rule matches it.
1081
+ */
1082
+ /**
1083
+ * A run of text under `parent`, which commits as `viewName`: the text itself inside a text, a
1084
+ * paragraph of its own inside any other view, and nothing where the view takes its text as a
1085
+ * prop (see `ViewNameOptions`) or the run is whitespace between a view's children.
1086
+ */
1087
+ private reconcileText;
1088
+ private looseText;
1089
+ /** Remember an iOS modal host committed as showing, so hiding it waits for `topDismiss`. */
1090
+ private notePresented;
843
1091
  /**
844
1092
  * Whether a child is left out of its parent's commit: a modal host whose `visible` is false.
845
1093
  *
@@ -849,9 +1097,11 @@ export declare class Engine implements HostEngine {
849
1097
  * committed, with `visible` false, until native reports `topDismiss`: Modal.js keeps it that
850
1098
  * long so the dismissal animates and `(dismiss)` fires. Android drops it at once, as Modal.js
851
1099
  * does there.
1100
+ *
1101
+ * A withheld host is unmounted, and Fabric drops an unmounted view's event target for good
1102
+ * (`EventEmitter::setEnabled`), so its committed handles are forgotten and it is created afresh
1103
+ * when it is shown again, as Modal.js creates it afresh. Committed again, it ignores every touch.
852
1104
  */
853
- /** Remember an iOS modal host committed as showing, so hiding it waits for `topDismiss`. */
854
- private notePresented;
855
1105
  private withheld;
856
1106
  /**
857
1107
  * `reconcileChildren` for a node other nodes hoist into: its own children, each followed by
@@ -870,7 +1120,15 @@ export declare class Engine implements HostEngine {
870
1120
  * Its native state goes with it, as it would there.
871
1121
  */
872
1122
  private reconcileUnder;
873
- /** Let a node and everything under it be created again at the next commit. */
1123
+ /**
1124
+ * A node whose native view is no longer the one it was created as is created again: a text
1125
+ * element that came to hold a view, or stopped. A clone keeps the view it was made as.
1126
+ */
1127
+ private forgetRenamed;
1128
+ /**
1129
+ * Let a node and everything under it be created again at the next commit. The views it keeps
1130
+ * for hoisted names go too: they are children of the native view it is losing.
1131
+ */
874
1132
  private forgetCommitted;
875
1133
  /** A hoisted node, which commits into an ancestor further up than the parent it is in. */
876
1134
  private committedElsewhere;
@@ -896,7 +1154,7 @@ export declare class Engine implements HostEngine {
896
1154
  private create;
897
1155
  /**
898
1156
  * Angular's own unknown-element check does not run in this pipeline, so a `<text>` in a
899
- * template that never imported `Text` compiles, renders as a plain view, and looks like a
1157
+ * template that never imported `Text` compiles, draws without the component, and looks like a
900
1158
  * layout bug. On the first commit of any known element with no component behind it, say so.
901
1159
  */
902
1160
  private checkClaimed;
@@ -910,6 +1168,12 @@ export declare class Engine implements HostEngine {
910
1168
  private readonly undefinedTokens;
911
1169
  /** Said once per name: a phone has no inspector to show the declaration struck out. */
912
1170
  private reportUndefinedToken;
1171
+ private readonly unreadDisplays;
1172
+ /**
1173
+ * Said once per token and value: the compiler refuses `display: grid` written out, but a token
1174
+ * is only known here, and without this the view lays out as flex with nothing said.
1175
+ */
1176
+ private reportUnreadDisplay;
913
1177
  private checkProps;
914
1178
  private isDeclared;
915
1179
  /**
@@ -1023,6 +1287,11 @@ export declare class Engine implements HostEngine {
1023
1287
  private isAttached;
1024
1288
  /** The host's `resolveAssetSource`, for a component that needs an asset's size up front. */
1025
1289
  resolveAsset(value: unknown): unknown;
1290
+ /**
1291
+ * A colour prop as native takes it. A shape's `fill` or `stroke` the cascade settled from a
1292
+ * token is the solid brush react-native-svg takes, and `none` no paint at all.
1293
+ */
1294
+ private painted;
1026
1295
  /**
1027
1296
  * The host's `processColor`, and the one place a platform colour becomes one.
1028
1297
  *